用 SML 判断数字是奇数还是偶数

Tell if number is odd or even with SML

这是我一直在研究的第二个 SML 程序。这些函数是相互递归的。如果我调用 odd(1) 我应该得到 true 而 even(1) 我应该得到 false。这些函数应该适用于所有正整数。但是,当我 运行 这个程序时:

fun
    odd (n) = if n=0 then false else even (n-1);
and
    even (n) = if n=0 then true else odd (n-1);

我得到:

[opening test.sml]
test.sml:2.35-2.39 Error: unbound variable or constructor: even
val it = () : unit

我该如何解决这个问题?

问题是中间的分号(;)。允许在完整声明的末尾使用分号(可选),但在 and 之前不是声明的结尾!

所以编译器在引用未声明的 even 的无效声明 fun odd (n) = if n=0 then false else even (n-1) 上崩溃了。如果要继续,它接下来会在声明开始时因 and 的非法出现而爆炸。


请注意,分号只有两种情况才有意义:

  • 符号 (...A... ; ...B... ; ...C...) 表示“计算 ...A......B......C...,以及 return ...C... 的结果。
    • 同样是符号 let ... in ...A... ; ...B... ; ...C... end,其中括号是可选的,因为 in ... end 足以将其内容括起来。
  • 如果您使用的是交互式 REPL(读取-评估-打印循环),则顶级声明末尾的分号表示 "OK, now actually go ahead and elaborate/evaluate/etc. everything so far"。

在上述情况之外,Idiomatic Standard ML 并不真正使用分号;但这样做是可以的,只要您不开始考虑过程语言并期望分号为 "terminate statements" 或类似的东西。 ; 在标准 ML 中的使用与 ; 在 C 及其语法后代等语言中的使用之间显然存在关系,但不是直接关系。

我确信使这些函数递归有一个教学点,但这里有一些更短的函数:

fun even x = x mod 2 = 0
val odd = not o even