SML - 错误:子句的右侧与函数结果类型[圆度]不一致

时间:2013-02-21 21:06:09

标签: sml smlnj

请考虑以下代码:

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),为什么会出错呢?

由于

2 个答案:

答案 0 :(得分:3)

由于g有一个参数,因此其类型为'X -> 'Y

h(b) = g(a)表示hg必须具有相同的结果类型'Y
h的类型为'Z -> 'Y

因此,对于g(x)类型的任何x,'X必须具有'Y类型。
g(x)的返回值为h,其类型为'Z -> 'Y 这意味着'Y必须与'Z -> 'Y的类型相同,这是不可能的。

正如SML所说,'Z -> 'Yh的类型)与'Yg(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

这次你的关闭只有一个身体。但这没有任何意义......只是为什么你会出现循环错误的一个例子。