gpt4 book ai didi

scheme - Scheme中 'and'是怎么定义的?

转载 作者:行者123 更新时间:2023-12-01 10:51:15 31 4
gpt4 key购买 nike

Scheme中的'and'会忽略'除以0'的错误,比如(and (negative? (random 100)) (/1 0))返回#f。它是如何做到的?

i (define (∧ b₀ b₁) (if (not b₀) #f b₁)), (∧ (negative? (random 100)) (/1 0)) 仍然会出现“除以 0”的错误。

最佳答案

您不能将 直接定义为函数,因为 Scheme 是严格的——这意味着函数参数总是在传递给函数之前先求值。 p>

但是,您可以使用宏定义适当的短路。这是 Racket 中最简单的版本:

(define-syntax-rule (my-and a b) (if a b #f))

或使用标准 Scheme 中的 syntax-rules 的等效形式:

(define-syntax my-and
(syntax-rules ()
[(_ a b) (if a b #f)]))

宏不是普通函数。相反,它是一种在编译时运行的句法转换。当您在代码中使用新的 and 时,它会“扩展”为相应的 if 表达式。所以:

(my-and #f (/ 1 0))

变成

(if #f (/ 1 0) #f)

在你的程序运行之前。由于 if 内置于语言中,因此它具有正确的行为。

由于宏不是函数,这也意味着您不能作为参数传递。因此,您不能直接使用 编写折叠——您必须将其包装到 lambda 中。

为了更忠实于原始的 and,您可以定义 my-and 通过使宏递归来获取任意数量的参数。要在宏中定义“剩余参数”,您可以使用特殊的 ... 关键字:

(define-syntax my-and
(syntax-rules ()
[(_) #t]
[(_ a) a]
[(_ a b ...) (if a (my-and b ...) #f)]))

如果您使用的是像 Racket 的 #lang lazy 或 Haskell 这样的惰性语言,那么您不需要在这里使用宏。您可以直接定义 :

#lang lazy
(define (and a b) (if a b #f))

或者在 Haskell 中:

and a b = if a then b else False

并且它将具有正确的行为,作为一个正常的函数。您可以将此 and 传递给折叠,它甚至会在遇到 False 时立即停止评估列表!看一看:

Prelude> foldl and True [True, False, error "fail"]
False

(Haskell 中的error 错误输出就像1/0。由于Haskell 是静态类型的, 的参数必须是 bool 值所以你不能直接使用1/0。)

关于scheme - Scheme中 'and'是怎么定义的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19761945/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com