我正在尝试将fold与++结合使用。它应该在我检查它的类型时起作用:
> :t foldl (++)
foldl (++) :: Foldable t => [a] -> t [a] -> [a]
当我尝试像这样使用它
> foldl (++) [1] [1,2,3]
我收到如下错误:
约束中的非类型变量参数:Num [a] (使用FlexibleContexts允许这样做)
我在做什么错了?
答案 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]
。