问题描述
我正在通过Haskell从第一原则编程。在折叠列表一章中,练习5f,当我评估时,
foldr const'a'[1..5]
我得到
然而,
foldl const'a'[1..5]
我得到'a'
。
我得到褶皱是懒惰的, foldr
不会穿过脊椎,而 foldl
却会。但是,即使是在查看foldr和foldl的定义,
foldr fz [] = z
foldr fz(x: xs)= fx(foldr fz xs)
foldl fz [] = z
foldl fz(x:xs)= foldl f(fzx)xs
我无法弄清楚为什么会出现这种类型的错误。我猜测编译器是根据<$ c $的类型推断 x
( Num
)的类型因为 const
( Char
),但我看不到它在哪里绘制连接。 c $ c>或 f
并不要求它的两个参数是相同的类型。
有什么想法?
确定看看 foldr ::(a - > b - > b ) - > b - > [a] - > b
从右边开始,显然必须有 a
是 Num
和 Enum
(因为您使用 [1..5]
)
接下来你传入'a'
,所以你有 b〜Char
最后,您的函数有 const
- 而const是 const :: a - > b - > a
- 请注意您现在必须拥有 a〜b
,因为您统一了
a - > b - > b
a - > b - > a
^^^^^
但这当然意味着'a'
必须是 Num
其中 Char
的实例值不是......这是你的错误(它是在抱怨1,因为从左边开始,而不是问题变得明显)
foldl
在另一侧具有 foldl ::(b - > a - > b) - > b - > [a] - > b
所以现在您再次 a
Num , b
必须再次为 Char
,但现在 const
恰好符合(在类型const中切换 b
和 a
)
I'm working through "Haskell Programming From First Principles". In the chapter on Folding Lists, exercise 5f,
when I evaluate
foldr const 'a' [1..5]
I get
However, with
foldl const 'a' [1..5]
I get 'a'
.
I get that the folds are lazy, foldr
doesn't traverse the spine and foldl
does. But even looking at the definitions of foldr and foldl,
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
I can't figure out why it would have this type error. I'm guessing that the compiler is inferring type of x
(Num
) based on the type of z
(Char
), but I can't see where it draws the connection, since const
or f
doesn't require its two arguments to be the same type.
Any thoughts?
ok look at the type of foldr :: (a -> b -> b) -> b -> [a] -> b
Starting from the right you obviously must have a
be some instance of Num
and Enum
(because you use [1..5]
)
Next you pass in 'a'
so you have b ~ Char
Finally you have const
for the function - and const is const :: a -> b -> a
- note how you now must have a ~ b
because you unify
a -> b -> b
a -> b -> a
^^^^^
but this of course would mean that 'a'
must be a value of an instance of Num
which Char
is not ... there is your error (it's complaining about the 1 because starting left instead it's the point where the the problem becomes obvious)
foldl
on the other side has foldl :: (b -> a -> b) -> b -> [a] -> b
so now you have again a
some instance of Num
, b
must again be Char
but now const
just fits in (just switch b
and a
in the type of const)
这篇关于Haskell foldr会导致类型错误,而foldl不会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!