【发布时间】:2016-06-15 12:20:28
【问题描述】:
在阅读有关修复的信息时,因为我对在我的代码中使用递归 lambdas 感兴趣,所以我遇到了这个特定的代码示例(来自 Here):
fix (\rec n -> if n == 0 then 1 else n * rec (n-1)) 5
现在忽略 fix 的类型签名,我觉得那段代码有问题:
修复的类型是 (a -> a) -> a 而 lambda 的类型是 (a -> a) -> a -> a 我确定我读错了这段代码,但我第一次读到它的方式是“修复应用于两个参数”这是错误的,因为 fix 只接受一个参数,一个函数 (a -> a),肯定有一些我明显遗漏的东西。
然后我查看了 lambda 的类型和修复的类型,在我看来“等等,不是有很大的不匹配吗?我可以理解,使用 curried 函数可以提供 @ 类型的函数987654325@ 没有足够的参数来创建新函数,但在这里我将 (a -> a) -> a -> a 提供给 (a -> a) -> a 函数,似乎我试图通过针孔传递大象,将错误的参数提供给修复函数.
我的内部解析器和类型检查器(brain 1.0)在评估这一行时哪里出错了?
【问题讨论】:
-
我想你是假设因为这两种类型中的类型变量都称为
a,所以它必须是相同的类型。情况并非如此——当你有一个函数fix :: (a -> a) -> a时,你真正拥有的是forall a . (a -> a) -> a。这里a可以被实例化为任何类型。在这种情况下,你有a ~ (x -> x)所以fix :: ((x -> x) -> (x -> x)) -> x -> x有两个参数。
标签: haskell recursion fixpoint-combinators