2016-03-02 50 views
1

当看到有关修复,因为我很感兴趣,在我的代码有递归lambda表达式我来到代码这个特殊的例子(从Here):Haskell的类型和修复递归的例子

fix (\rec n -> if n == 0 then 1 else n * rec (n-1)) 5 

现在忽略的类型签名修复我觉得这段代码错了:

修复类型是(a -> a) -> a,而lambda的类型是(a -> a) -> a -> a我确定我正在阅读这段代码错误,但我第一次阅读它的方式是“修复应用于两个参数”这是错误的,因为修复只接受一个参数,一个函数(a - > a),肯定会有一些我明显缺失的东西。

然后我看了一下lambda的类型和修复类型,它对我来说似乎“坚持,是不是有很大的不匹配?我可以理解,使用curried函数可以提供类型的函数a -> a -> a没有足够的论据来创建一个新的功能,但在这里我喂(a -> a) -> a -> a(a -> a) -> a功能,好像我试图通过针孔传递大象,喂错参数修复功能。

我的内部语法分析器和类型检查器(脑1.0)在评估这条线时出了什么问题?

+1

我想你是假设因为这两种类型的类型变量被称为'a',它必须是相同的类型。事实并非如此 - 当你有一个函数'fix ::(a - > a) - > a''你真正拥有的就是'a a。 (a→a)→a'。这里'a'可以被实例化为任何类型。在这种情况下,你有'a〜(x - > x)'所以'fix ::((x - > x) - >(x - > x)) - > x - > x'有两个参数。 – user2407038

回答

1

您可以读取lambda的类型为:

(b -> b) -> (b -> b) 

这可能会使它更清晰当你将它提供给fix时发生了什么。返回的值是另一个函数b -> b,然后在您的示例中立即应用参数5