【问题标题】:Haskell type and fix recursion examplesHaskell 类型和修复递归示例
【发布时间】: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


【解决方案1】:

您可以将 lambda 的类型读取为:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 2016-05-23
    • 1970-01-01
    • 2023-03-12
    • 2015-12-21
    • 2021-05-28
    • 1970-01-01
    相关资源
    最近更新 更多