为什么我会遇到无限类型错误

时间:2014-08-31 23:09:00

标签: haskell

我正在尝试使用折叠实现我自己的concat并在这里磕磕绊绊。为什么我会“无法创建无限类型”错误?

merge2 xs  = foldl conc ([]) xs
             where conc x y = (x : y) 

2 个答案:

答案 0 :(得分:1)

查看表达式x : y中x和y的类型 - 由于{{1}的定义,y的类型必须是x类型的列表。 }}。如果您尝试遵循:的类型,特别是其累加器函数的类型,您最终需要一个列表列表...

答案 1 :(得分:1)

在这里,您可以如何欺骗GHCi向您展示临时表达的类型。首先,你原来的定义,

f xs = foldl conc [] xs where conc x y = (x : y)

给出了关于"无限类型"的错误" a = [a]" 。现在,将conc中的foldl替换为其他内容:

f xs = foldl g [] xs where conc x y = (x : y) ; g = g

那里没有类型错误!如果仍有错误,请将某个表达式中使用的每个标识符替换为g2 = g2g3 = g3等。此类定义等同于定义g = undefined,其使用会导致错误,但更重要的是对我们而言根据需要,它的类型可以随意变成任何东西。

现在的诀窍是将它定义为一个简单的值,例如布尔值:

f xs = foldl g [] xs where conc x y = (x : y) ; g = True

这给我们一个关于" a - >之间类型不匹配的错误b - > a" " Bool" 。我们知道True的类型为Bool,因此我们得出结论:g必须是a -> b -> a类型。我们也可以使用:t命令直接找到它:

Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
         -------------

接下来,我们现在可以将conc与一些简单的值进行比较:

f xs = foldl g [] xs where conc x y = (x : y) ; g = g ; h = conc == True

我们再次在" a - >之间出现类型不匹配错误。 [a] - > [a]" " Bool" True :: Bool(类型为Bool),conc :: a -> [a] -> [a]。最初我们在g现在使用它,因此它们的类型必须匹配:

g    :: a -> b   -> a
conc :: a -> [a] -> [a]
                   ------
                   a ~ [a]

这是不可能的。

相关问题