2

想象一下,我有一个函数,其域的所有整数都大于 0。我希望其他输入的结果未定义。为了简单起见,假设这是增量函数。在 Haskell 中,我可以通过类似的方式实现这一点

f :: Integer -> Integer
f x 
  | x > 0 = x + 1
  | otherwise = undefined

当然,这个例子很简单,但应该清楚我想要实现的目标。我不确定如何在 Scheme 中实现类似的效果。

(define (f x)
  (if (> x 0)
      (+ x 1)
      (?????)))

我的想法是坚持error在那里,但有没有办法更紧密地复制 Haskell 行为?

4

4 回答 4

2

您的问题与这个问题有关,该问题的答案指出在 R5RS 中(我猜 MIT 方案部分支持?),ifwith one 分支返回一个“未指定的值”。所以等效于haskell代码应该是:

(define (f x)
  (if (> x 0)
      (+ x 1)))

你可能已经知道了:在 haskellundefined中是用 来定义的error,主要在开发中用作占位符,稍后将被删除。定义你的haskell函数的正确方法是给它一个类似的类型:Integer -> Maybe Integer

于 2013-01-01T21:17:09.667 回答
2

一个常见的未定义值void定义为(define void (if #f #f))

于 2013-01-01T23:53:25.600 回答
1

请注意,并非所有 Scheme 实现都允许if没有替代部分(如其他答案中所建议) - 例如,Racket 会将这种情况标记为错误。

在 Racket 中,您可以显式编写(void)以指定过程不返回有用的结果(检查这在 MIT 方案中是否可用)。从文档中:

#<void>大多数具有副作用且没有有用结果的表单和过程都会返回该常量。该常量#<undefined>用作 letrec 绑定的初始值。#<void>价值永远是eq?对自己的,价值#<undefined>也是eq?对自己的。

(void v ...) → void? 返回常量#<void>。每个v参数都被忽略。

也就是说,问题中的示例如下所示:

(define (f x)
  (if (> x 0)
      (+ x 1)
      (void)))
于 2013-01-02T02:23:12.307 回答
0

专门针对 MIT 计划,我相信 #!unspecific 是从 if 没有替代项返回的常量。

(eq? (if (= 1 2) 3) #!unspecific) => #t
于 2013-01-08T23:41:28.277 回答