在foldl和++一起使用时约束错误中的非类型变量参数

时间:2019-05-20 19:57:59

标签: haskell

我正在尝试将fold与++结合使用。它应该在我检查它的类型时起作用:

> :t foldl (++)
foldl (++) :: Foldable t => [a] -> t [a] -> [a]

当我尝试像这样使用它

> foldl (++) [1] [1,2,3]

我收到如下错误:

  

约束中的非类型变量参数:Num [a]       (使用FlexibleContexts允许这样做)

我在做什么错了?

1 个答案:

答案 0 :(得分:8)

我认为您误解了foldl (++)函数的类型,t在这里很重要:

foldl (++) :: Foldable t => [a] -> t [a] -> [a]

如果您将[1] :: Num n => [n]作为第一个参数传递,那没有问题,因为之后您的[1]的类型为[a],因此也是a ~ n

第二个参数是 。您在此处传递类型为[1,2,3] :: Num m => [m]或更规范的Num m => [m]的列表Num m => [] m。使其与t [a]匹配的唯一可能方法是设置t ~ []t是列表 type 构造函数),然后设置[a]应该与m匹配,但是Haskell不知道属于列表Num的{​​{1}}类型m,因此失败。

您可以通过以下方式调用它:

[a]

自Haskell以来,这里将生成一个类似于以下内容的表达式:

Prelude> foldl (++) [1] [[2], [3,4]]
[1,2,3,4]

等效于:

(([1] ++ [2]) ++ [3]) ++ [4]

我们还可以传递其他[1,2,3,4] 类型,例如Foldable

Maybe

在这种情况下,第二个参数应具有类型Prelude> foldl (++) [1] (Just [2]) [1,2] Prelude> foldl (++) [1] Nothing [1]