我知道Scheme和其他Lisp方言包括逻辑运算符,如' and‘和'or',但是,由于我目前正在学习Scheme,所以我正在编写自己的逻辑运算符。到目前为止,我对“或”的尝试是成功的(至少就我的测试所显示的情况而言)。我的逻辑或运算符如下:
(define (logical-or a b)
(if a true b))我试图为'and‘编写一个逻辑运算符,它也返回一个布尔值,但是我一直被卡住了。我尝试过任意数量的组合,但我只列出以下一个,它不返回布尔值:
(define (logical-and a b)
(if a b false))任何暗示或帮助欢迎。
发布于 2014-07-19 09:44:07
您的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因此,该计划的定义是:
(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),并且只有在必要时才计算它们的参数,所以真正的定义要复杂一些。
发布于 2014-07-19 19:07:16
正如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)。我们可以使用最简单的Scheme宏( syntax-rules )来完成这一任务
(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 ...)))))) 如果您尝试同样的,它将只显示"hello“一次。让我们尝试用新的宏编写我的初始过程:
(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)) ; ==> hellohttps://stackoverflow.com/questions/24837011
复制相似问题