Scheme - 逻辑运算符程序

时间:2014-07-19 05:12:03

标签: scheme

我知道Scheme和其他Lisp方言包括逻辑运算符,如'和'和'或',但是,因为我正在学习Scheme,我正在尝试编写自己的逻辑运算符。到目前为止,我对'或'的尝试都取得了成功(至少在我的测试显示给我的时候)。我的逻辑或运算符如下:

(define (logical-or a b)
   (if a true b))

我正在尝试为'和'编写一个逻辑运算符,它也返回一个布尔值,但我一直卡住了。我已经尝试了任意数量的组合,但我将列出以下一个组合,它不返回布尔值:

(define (logical-and a b)
(if a b false))

任何提示或帮助欢迎。

2 个答案:

答案 0 :(得分:2)

根据Uselpa的回答和提到的leppie的评论,运营商andor不会返回#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

如果用版本替换orand,程序将永远不会停止评估递归。

我们知道我们可以使用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个值,但由于内置andor运算符允许任意数量的参数(甚至为0),并且只在必要时评估其参数,因此实际定义更多一些复杂。