我知道Scheme和其他Lisp方言包括逻辑运算符,如'和'和'或',但是,因为我正在学习Scheme,我正在尝试编写自己的逻辑运算符。到目前为止,我对'或'的尝试都取得了成功(至少在我的测试显示给我的时候)。我的逻辑或运算符如下:
(define (logical-or a b)
(if a true b))
我正在尝试为'和'编写一个逻辑运算符,它也返回一个布尔值,但我一直卡住了。我已经尝试了任意数量的组合,但我将列出以下一个组合,它不返回布尔值:
(define (logical-and a b)
(if a b false))
任何提示或帮助欢迎。
答案 0 :(得分:2)
根据Uselpa的回答和提到的leppie的评论,运营商and
和or
不会返回#t
,但不会返回#f
(and 'these 'are 'all 'true 'values) ; ==> values
(or 'these 'are 'all 'true 'values) ; ==> these
决定了表格的结果。因此
and
逻辑运算符or
和(define (first-true-value lst)
(and (pair? lst)
(or (car lst)
(first-true-value (cdr lst)))))
(first-true-value '()) ; ==> #f
(first-true-value '(#f #f)) ; ==> #f
(first-true-value '(#f #f hello)) ; ==> hello
是短路的,因此它们不是程序。想象一下这个程序:
and
如果用版本替换or
和and
,程序将永远不会停止评估递归。
我们知道我们可以使用if
重写(and)
。 #t
为(and a)
,a
为(and a b ...)
,(if a (and b ...) #f)
为syntax-rules
。我们可以用最简单的Scheme宏(define-syntax logical-and
(syntax-rules ()
((logical-and) #t)
((logical-and a) a)
((logical-and a b ...)
(if a (logical-and b ...) #f))))
:
or
我们也可以(or)
同样的方式做。 #f
为(or a b ..)
,(if a a (or b ...))
为(define-syntax logical-or
(syntax-rules ()
((logical-or) #f)
((logical-or a b ...) ; NB: zero elements match "b ..."
(if a a (logical-or b ...)))))
:
a
此问题存在问题,因为它使用了(logical-or (display "hello"))
两次。请尝试(display "hello")
。它将评估let
,从而显示文本两次。要解决此问题,我们需要将值包装在(define-syntax logical-or
(syntax-rules ()
((logical-or) #f)
((logical-or a b ...)
(let ((tmp a))
(if tmp
tmp
(logical-or b ...))))))
:
(define (first-true-value lst)
(logical-and (pair? lst)
(logical-or (car lst)
(first-true-value (cdr lst)))))
;; and we test them:
(first-true-value '()) ; ==> #f
(first-true-value '(#f #f)) ; ==> #f
(first-true-value '(#f #f hello)) ; ==> hello
如果你尝试相同,它只会显示"你好"一旦。让我们尝试用新的宏编写我的初始程序:
{{1}}
答案 1 :(得分:1)
你的logical-or
并不总是返回布尔值:
> (logical-or #f 2)
2
正如@leppie所说,任何不虚假的东西(#f)在Scheme中都是正确的;尝试使用内置or
函数进行一些实验:
> (or 1 2)
1
> (or #f 2)
2
> (or #t 2)
#t
> (or 1 #f)
1
> (or #f #t)
#t
所以Scheme中的定义是:
(define (my-or a b)
(if a a b))
同样,and
:
> (and 1 #t)
#t
> (and 1 #f)
#f
> (and 1 2)
2
> (and #f 2)
#f
> (and #t 2)
2
所以定义是
(define (my-and a b)
(if a b a))
如果您只想返回布尔值,那么您需要编码
(define (logical-or a b)
(cond
(a #t)
(b #t)
(else #f)))
(define (logical-and a b)
(if a
(if b
#t
#f)
#f))
这适用于2个值,但由于内置and
和or
运算符允许任意数量的参数(甚至为0),并且只在必要时评估其参数,因此实际定义更多一些复杂。