如果我定义
fun id x = x
然后自然id
有类型'a -> 'a
当然,id 0
计算结果为0
,这很有意义。
既然这很有意义,我应该可以用一个函数来封装它:
fun applyToZero (f: 'a -> 'a) = f 0
希望applyToZero
有类型('a -> 'a) -> int
并applyToZero id
评估为0
但是当我尝试applyToZero
如上所述定义时,SML/NJ 给出了一个奇怪的错误消息,它开始:
unexpected exception (bug?) in SML/NJ: Match [nonexhaustive match failure]
raised at: ../compiler/Elaborator/types/unify.sml:84.37
这几乎看起来像是编译器本身的一个错误。很奇怪,但可能。
但是 PolyML 也不喜欢它(尽管它的错误消息不那么奇怪):
> fun applyToZero (f: 'a -> 'a) = f 0;
poly: : error: Type error in function application.
Function: f : 'a -> 'a
Argument: 0 : int
Reason: Can't unify int to 'a (Cannot unify with explicit type variable)
Found near f 0
以下确实有效:
fun ignoreF (f: 'a -> 'a) = 1
与推断类型('a -> 'a) -> int
。这表明创建这种类型的高阶函数并非不可能。
为什么 SML 不接受我的定义applyToZero
?是否有任何解决方法可以让我定义它以使其类型为('a -> 'a) -> int
?
动机:在我试图解决这个问题的难题时,我能够定义一个tofun
类型的函数int -> 'a -> 'a
和另一个fromfun
具有所需属性的函数,该属性fromfun (tofun n) = n
适用于所有整数n
。但是,我工作的推断类型fromfun
是('int -> 'int) -> 'int)
. 我尝试添加类型注释以便 SML 将其视为('a -> 'a) -> int
失败的所有尝试。我不想显示我的定义,fromfun
因为提出该问题的人可能仍在研究该难题,但applyToZero
触发的定义完全相同的错误消息。