3

在 miniKanren 中,succeed可以定义为(define succeed (== #t #t)),并且fail可以定义为(define fail (=== #t #f))。但是,和在The Reasoned Schemer中出现的#sand#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]

我觉得这与阅读器宏有关。

如何在 Scheme 和 Racket 中定义#sforsucceed#ufor ?fail

我正在使用Scheme规范 miniKanren 实现和 Racket的规范 miniKanren 实现。

4

3 回答 3

3

Racket 中的标识符不能以 . 开头#。绑定标识符su. #s重新定义and的含义#u并不那么简单,因为它需要发生在读者身上。通常#something向读者发出信号,表明要阅读一些特别的东西。输入(foo bar)将作为列表读取,#(foo bar)将作为向量读取,并将#s(foo bar)作为结构读取。您可以在此处阅读有关标准语法的信息:

https://docs.racket-lang.org/reference/reader.html?q=%23s#%28mod-path._reader%29

现在如果你想改变它的含义,#s#u需要查看 readtables。每次读者看到#它时,它都会查阅一个可读表以了解如何处理以下字符。由于读取发生在解析/扩展和评估之前,您不能简单地通过调用程序中的函数来更改读取器。您将需要使用#reader扩展机制或创建自己的语言。

有关 readtables 的更多信息: https ://docs.racket-lang.org/reference/readtables.html?q=reader-macro

该指南有一个如何使用阅读器扩展的示例: https ://docs.racket-lang.org/guide/hash-reader.html

于 2019-07-22T15:30:24.863 回答
1

我解决了所有的书使用

(define succeed
  (lambda (s)
    `(,s)))
(define SUCC succeed)

(define fail
  (lambda (s)
    '()))

另一方面,您应该查阅Friedman & Byrd 提供的源代码。我使用 mit-scheme 解决了它——没有使用球拍的特定功能,R6RS 就足够了。

于 2019-07-23T09:59:04.153 回答
1

对于 Racket,#s可以#u这样定义(参考:Using Racket for The Reasoned Schemer):

;; #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通过修改readtable

对于 Scheme,添加读取语法是在SRFI-10 尖逗号外部形式中定义的,但是#,()对于大多数人来说,生成的形式可能很尴尬。对于 Scheme,最好只定义sand ,u因为目前没有可移植的方式来定义#sand #u

于 2019-07-26T07:23:06.227 回答