首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在SML中,为什么不允许在模式中使用真正的常量?

在SML中,为什么不允许在模式中使用真正的常量?
EN

Stack Overflow用户
提问于 2016-12-08 16:18:44
回答 1查看 250关注 0票数 2

本守则不获接纳;

代码语言:javascript
复制
> fun fact 0.0 = 1.0
Error-Real constants not allowed in patterns
> | fact n = n*fact(n-1);
Static Errors

为什么会这样呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-08 16:36:28

real不是相等类型。SML非常重视生成可证明正确的代码。比较两个实数是否相等通常并不是一个坏主意,因为在数学上可能是x = y,但是由于运行时的舍入错误,x != y在运行时是这样的。这是一个臭名昭著的错误来源,在天真的数字算法的实现。由于SML经常是个糟糕的主意,所以SML干脆禁止它。因此,不可能将输入的相等性与模式1.0进行比较,因此允许输入作为模式是没有意义的。

在相对较少的情况下,您确实希望比较两个reals是否相等,可以使用x <= y andalso x => y。或者(正如@AndreasRossberg所指出的),我们可以使用标准库函数Real.==,它与Real.==(x,y)一样使用。最后一个看起来有点奇怪,所以您可以将它声明为infix操作符:

代码语言:javascript
复制
val ==  = Real.==
infix 4 ==

但不幸的是,这两种方法都不能转化为模式,尽管它们确实使编写以下内容成为可能:

代码语言:javascript
复制
fun fact x = if x == 0.0 then 1.0 else x * fact(x-1.0) 

它的工作原理可能和预期一样。另一方面,正如@SimonShine所指出的,如果输入的输入不是n.0格式( n是int )(即使这仅仅是由于舍入错误),它就会崩溃。这正是SML的创建者试图防止的问题。定义fact以获取和返回It更有意义:

代码语言:javascript
复制
fun fact x = if x = 0 then 1 else x * fact(x-1)

(或者读一读伽马函数,如果你真的想要一个浮点阶乘)。

最后一个定义可以很容易地转换为您似乎正在尝试的模式匹配形式。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41044051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档