为什么来自 miniKanren 的 "disj" 在 Scheme 中有效,但在 Racket 中无效?
Why does "disj" from miniKanren work in Scheme but not in Racket?
我正在使用 Racket 的 minikanren 库,但想使用“disj”和“conj”运算符。为了易读性,我希望能够更明确地声明我使用的是 disj 还是 conj,而不是必须通过 conde 表达式进行解析,尤其是当表达式变得更加复杂时。我从“合理的阴谋家”复制了来源:
(define (append∞ s∞ t∞)
(cond
((null? s∞) t∞)
((pair? s∞)
(cons (car s∞)
(append∞ (cdr s∞) t∞)))
(else (λ ()
(append∞ t∞ (s∞))))))
(define (disj2 g1 g2)
(λ (s)
(append∞ (g1 s) (g2 s))))
(define-syntax disj
(syntax-rules ()
[(disj) '()]
[(disj g) g]
[(disj g0 g ...) (disj2 g0 (disj g ...))]))
这适用于前两种情况
> (run* (x) (disj (== 'foo x)))
'(foo)
但只有 returns 使用多个目标时的第一个结果:
> (run* (x) (disj (== 'foo x) (== 'bar x) (== 'foobar x)))
'(foo)
这是为什么?
哼。我似乎无法重现该行为。
当我克隆 TRS/2e repo 时,添加两者
#lang racket
(provide (all-defined-out))
到trs2-impl.scm
、运行那个文件的顶部,然后尝试你的测试程序我看到了预期的结果:
;
; Welcome to Racket v7.9.0.3 [cs].
;
trs2-impl.scm> (run* (x) (disj (== 'foo x) (== 'bar x) (== 'foobar x)))
'((foo) (bar) (foobar))
你看到不同的行为了吗?如果是这样,那么我们可以看得更深。您知道您使用的是哪个版本的 Racket 吗?我认为这无关紧要,但以防万一。
我正在使用 Racket 的 minikanren 库,但想使用“disj”和“conj”运算符。为了易读性,我希望能够更明确地声明我使用的是 disj 还是 conj,而不是必须通过 conde 表达式进行解析,尤其是当表达式变得更加复杂时。我从“合理的阴谋家”复制了来源:
(define (append∞ s∞ t∞)
(cond
((null? s∞) t∞)
((pair? s∞)
(cons (car s∞)
(append∞ (cdr s∞) t∞)))
(else (λ ()
(append∞ t∞ (s∞))))))
(define (disj2 g1 g2)
(λ (s)
(append∞ (g1 s) (g2 s))))
(define-syntax disj
(syntax-rules ()
[(disj) '()]
[(disj g) g]
[(disj g0 g ...) (disj2 g0 (disj g ...))]))
这适用于前两种情况
> (run* (x) (disj (== 'foo x)))
'(foo)
但只有 returns 使用多个目标时的第一个结果:
> (run* (x) (disj (== 'foo x) (== 'bar x) (== 'foobar x)))
'(foo)
这是为什么?
哼。我似乎无法重现该行为。
当我克隆 TRS/2e repo 时,添加两者
#lang racket
(provide (all-defined-out))
到trs2-impl.scm
、运行那个文件的顶部,然后尝试你的测试程序我看到了预期的结果:
;
; Welcome to Racket v7.9.0.3 [cs].
;
trs2-impl.scm> (run* (x) (disj (== 'foo x) (== 'bar x) (== 'foobar x)))
'((foo) (bar) (foobar))
你看到不同的行为了吗?如果是这样,那么我们可以看得更深。您知道您使用的是哪个版本的 Racket 吗?我认为这无关紧要,但以防万一。