【问题标题】:Why is this form of acceptable, but the other form raises a type error?为什么这种形式可以接受,但另一种形式会引发类型错误?
【发布时间】:2010-07-24 21:24:42
【问题描述】:

在处理Real World Haskell 时,我尝试使用以下代码解决方案完成回文练习:

palin :: [a] -> [a]
palin list = list ++ rev list
    where rev list
           | null list = []
           | otherwise = rev (tail list) ++ (head list)

这引发了“无法构造无限类型错误。但是,只需将头部列表周围的括号替换为方括号,它就可以正常工作,如下例所示:

palin :: [a] -> [a]
palin list = list ++ rev list
    where rev list
           | null list = []
           | otherwise = rev (tail list) ++ [head list]

我真的不明白它为什么重要,也不明白“无法​​构造无限类型 a = [a]”错误是什么意思。有人可以解释一下吗?

【问题讨论】:

  • (something) never 形式的表达式与 [something] 形式的相应表达式具有相同的类型,您只需将括号替换为方括号即可。这总是很重要!

标签: haskell


【解决方案1】:

在最后一行中,您尝试将非列表附加到列表中。 head list 给出列表的第一项,即类型 a。当您尝试使用++ 追加时,您不能将不是列表的内容追加到列表中。通过附加 [head list],您将 1 个项目的列表附加到另一个列表。在这种情况下,[] 构造了单个项目列表。

【讨论】:

    【解决方案2】:

    假设你是类型检查员,你看到了这样的:

    (tail list) ++ (head list)
    

    你已经知道了,`list 是一些东西的列表。所以你开始:

    list::[a]
    

    那么这一定是真的:

    (tail list)::[a]
    

    还有这个:

    (head list)::a
    

    但是还有 `++ 希望它的两个参数都具有 相同的 类型。但这意味着,

    a == [a] 
    

    或通过替换:

    a == [a] == [[a]] == [[[a]]] ...etc.
    

    确实是无限类型。

    【讨论】:

      【解决方案3】:

      ++ 运算符的类型为[a] -> [a] -> [a],即它接受两个某种类型的列表并生成另一个相同类型的列表。 OTOH head 函数的类型为 [a] -> a,即它采用某种类型的列表并返回该类型的值。在您的第一个示例中,++ 在左侧得到[a],在右侧得到a。试图统一这些类型的类型检查器会产生该错误。在第二个示例中,您从head 的结果构造了一个单元素列表,它的类型为[a],所以类型检查器很高兴。

      【讨论】:

        猜你喜欢
        • 2015-10-04
        • 2014-02-07
        • 2010-10-06
        • 1970-01-01
        • 2012-10-23
        • 1970-01-01
        • 2011-03-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多