请考虑以下代码:
fun g(a) =
let fun h(b)=g(a)
in h end;
当我在SML中运行时,我得到:
- fun g(a) =
= let fun h(b)=g(a)
= in h end;
stdIn:55.5-57.10 Error: right-hand-side of clause doesn't agree with function re
sult type [circularity]
expression: 'Z -> 'Y
result type: 'Y
in declaration:
g = (fn a => let val <binding> in h end)
我无法理解这里的问题:g(a)
返回h
,但是
我没有在声明fun g(a)
中看到任何具体的返回值(即没有
fun g(a):int
),为什么会出错呢?
由于
答案 0 :(得分:3)
由于g
有一个参数,因此其类型为'X -> 'Y
。
h(b) = g(a)
表示h
和g
必须具有相同的结果类型'Y
,
h
的类型为'Z -> 'Y
。
因此,对于g(x)
类型的任何x,'X
必须具有'Y
类型。
但g(x)
的返回值为h
,其类型为'Z -> 'Y
这意味着'Y
必须与'Z -> 'Y
的类型相同,这是不可能的。
正如SML所说,'Z -> 'Y
(h
的类型)与'Y
(g(a)
的类型)不一致。
如果你试图手工解决,你会发现
g 1
将是一个函数h
,以便
h 3
是
的值g 1
这是一个函数h
,这样......
依此类推,无限期。
答案 1 :(得分:1)
ML类型推理系统首先将你的函数g识别为一个带有'Z并返回'Y的表达式。但后来它发现g的结果类型只是'Y,也是早期绑定h的结果类型。可以预期看到Z型 - >的结合。 Z-> Y.但是,您的函数闭包有一个本身的环境。所以这就像绑定g一样。
fun g a= g
如果你的闭包有一个本身就是环境的话,ML类型推断也无法猜测类型。
您可以按如下方式声明这些功能。
fun g(a) =
let
fun h(b)=g(a)
in
h(a)
end;
就像
fun g a = g a
这次你的关闭只有一个身体。但这没有任何意义......只是为什么你会出现循环错误的一个例子。