在miniKanren中,succeed可以定义为(define succeed (== #t #t)),fail可以定义为(define fail (=== #t #f))。但是#s和#u作为succeed和fail的短形式又如何呢,就像它们出现在理性的阴谋家中一样。
(define #s succeed)在球拍中产生一个错误:
Welcome to Racket v7.2.
> (require Racket-miniKanren/miniKanren/mk)
> (define #s succeed)
; readline-input:2:8: read-syntax: expected `(`, `[`, or `{` after `#s` [,bt
; for context]
#<procedure:...iniKanren/mk.rkt:337:4>
; readline-input:2:18: read-syntax: unexpected `)` [,bt for context]我觉得这与读取器宏有关。
我如何定义#s的succeed和#u的fail在计划和在球拍?
发布于 2019-07-22 15:30:24
球拍中的标识符不能以#开头。绑定标识符s和u非常简单。重新定义#s和#u的含义并不是那么简单,因为它需要发生在读者中。通常情况下,#something向读者发出信号,表示要读一些特别的东西。输入(foo bar)将被读取为一个列表,#(foo bar)将被读取为一个向量,而#s(foo bar)将被读取为一个结构。您可以在这里阅读有关标准语法的内容:
现在,如果要更改#s和#u的含义,则需要查看可读表。每次读者看到一个#时,它都会咨询一个可读的,看看如何处理以下字符。因为阅读发生在解析/扩展和评估之前,所以不能简单地通过调用程序中的函数来更改阅读器。您需要使用#reader扩展机制或创建自己的语言。
有关可读性的更多信息:https://docs.racket-lang.org/reference/readtables.html?q=reader-macro
指南中有一个如何使用读取器扩展的示例:https://docs.racket-lang.org/guide/hash-reader.html
发布于 2019-07-23 09:59:04
我把所有的书都用
(define succeed
(lambda (s)
`(,s)))
(define SUCC succeed)
(define fail
(lambda (s)
'()))另一方面,您应该参考Friedman & Byrd提供的源代码。我用麻省理工学院解决了它--方案--没有使用球拍的具体特性,R6RS就足够了。
发布于 2019-07-26 07:23:06
对于球拍,#s和#u可以定义为这样(参考:为推理的阴谋家使用球拍):
;; #s for succeed.
(current-readtable
(make-readtable (current-readtable)
#\s
'dispatch-macro
(lambda (ch port src line col pos) succeed)))
;; #u for fail.
(current-readtable
(make-readtable (current-readtable)
#\u
'dispatch-macro
(lambda (ch port src line col pos) fail)))请注意,这只在REPL中有效。
这通过修改#s和#u来定义可读性。
对于Scheme,添加读语法是在SRFI-10尖-逗号外部形式中定义的,但是结果的#,()表单对于大多数人来说可能是很尴尬的。对于Scheme,最好只定义s和u,因为目前还没有可移植的方法来定义#s和#u。
https://stackoverflow.com/questions/57133822
复制相似问题