想象一下,我的函数的所有整数都大于0的域。我希望其他输入的结果是未定义的。为简单起见,我们假设这是增量函数。在Haskell中,我可以通过类似
的方式实现这一点f :: Integer -> Integer
f x
| x > 0 = x + 1
| otherwise = undefined
当然,这个例子非常简洁,但应该清楚我想要实现的目标。我不确定如何在Scheme中实现类似的功能。
(define (f x)
(if (> x 0)
(+ x 1)
(?????)))
我的想法是在那里粘贴error
,但有没有办法更密切地复制Haskell行为?
答案 0 :(得分:2)
您的问题与this one有关,其答案指出在R5RS中(我猜MIT方案部分支持?),带有一个分支的if
返回“未指明的价值”。所以等同于haskell代码应该是:
(define (f x)
(if (> x 0)
(+ x 1)))
您可能已经知道:haskell undefined
是根据error
定义的,主要用于开发中作为占位符以便稍后删除。定义haskell函数的正确方法是给它一个类型:Integer -> Maybe Integer
。
答案 1 :(得分:2)
常见的未定义值void
定义为(define void (if #f #f))
。
答案 2 :(得分:1)
请注意,并非所有的Scheme实现都允许if
没有备用部分(如其他答案所示) - 例如,Racket会将此情况标记为错误。
在Racket中,您可以显式写(void)
来指定过程不返回有用的结果(检查它是否在MIT Scheme中可用)。来自documentation:
大多数形式和过程都会返回常量
#<void>
,这些形式和过程具有副作用且没有用处。常量#<undefined>
用作letrec绑定的初始值。#<void>
值始终为eq?
,#<undefined>
值也为eq?
。
(void v ...) → void?
返回常量#<void>
。每个v
参数都被忽略。
也就是说,问题中的示例如下所示:
(define (f x)
(if (> x 0)
(+ x 1)
(void)))
答案 3 :(得分:0)
特别针对麻省理工学院计划,我相信#!unspecific是从没有替代方案返回的常量。
(eq? (if (= 1 2) 3) #!unspecific) => #t