Ton*_*aro 2 constants sml polyml
此代码不被接受;
> fun fact 0.0 = 1.0
Error-Real constants not allowed in patterns
> | fact n = n*fact(n-1);
Static Errors
Run Code Online (Sandbox Code Playgroud)
为什么是这样?
real不是一个平等的类型.SML非常重视生成可证明正确的代码.比较两个实数是否相等往往是一个坏主意,因为它可能是x = y 数学上的情况,但由于舍入误差,x != y在运行时.这是数字算法天真实现中臭虫的臭名昭着的来源.因为它经常是一个坏主意,SML只是禁止它.由于无法将输入与模式进行比较1.0,因此将其作为模式进行比较是没有意义的.
在相对较少的情况下,您真的想要比较两个实数是否相等,您可以使用x <= y andalso x => y.或者(正如@AndreasRossberg指出的那样),可以使用标准库函数Real.==,就像使用它一样Real.==(x,y).这最后看起来有点奇怪,所以你可以将它声明为一个中缀运算符:
val == = Real.==
infix 4 ==
Run Code Online (Sandbox Code Playgroud)
然后简单地x == y遗憾的是,这些都不能变成一种模式,尽管它们确实可以写成:
fun fact x = if x == 0.0 then 1.0 else x * fact(x-1.0)
Run Code Online (Sandbox Code Playgroud)
这可能是有意的.在另一方面,作为@SimonShine指出,这将如果你给它的任何输入,崩溃不是形式的n.0地方n是一个int(即使这仅仅是由于舍入误差).这正是SML的创建者试图阻止的那种问题.定义fact获取和返回int 更有意义:
fun fact x = if x = 0 then 1 else x * fact(x-1)
Run Code Online (Sandbox Code Playgroud)
(或者 - 如果你真的想要一个浮点因子,请阅读伽玛函数).
最后一个定义可以很容易地转换为您似乎正在尝试的模式匹配形式.