[英]How to use foldl with operator
I thought that two codes should run properly 我认为两个代码应该可以正常运行
foldr (:) [] [1..5]
foldl (:) [] [1..5]
But I get error use foldl: 但是我使用foldl时出错:
Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [a] -> [a] -> [a]
Actual type: a -> [a] -> [a]
Relevant bindings include it :: [a] (bound at <interactive>:253:1)
In the first argument of ‘foldl’, namely ‘(:)’
In the expression: foldl (:) [] [1 .. 5]
Why foldl not run? 为什么foldl不运行?
The type signatures for foldl
and foldr
are slightly different in the function argument (they have switched arguments): foldl
和foldr
的类型签名在函数参数中稍有不同(它们具有切换的参数):
foldl :: (b -> a -> b) -> b -> t a -> b
foldr :: (a -> b -> b) -> b -> t a -> b
For foldl
to work you can use flip
which swaps the arguments of a function: 为了使foldl
正常工作,您可以使用flip
来交换函数的参数:
flip :: (a -> b -> c) -> b -> a -> c
Ie this should work: 即这应该工作:
foldl (flip (:)) [] [1..5]
Let's start by its equations: 让我们从其方程式开始:
foldl :: (b -> a -> b) -> b -> [a] -> b
foldl op z [] = z
foldl op z (x:xs) = foldl op (op z x) xs
The big difference between foldr
and foldl
is how the operator op
works: foldl
is tail recursive and applies the operator from left to right in contrast to foldr
which does the oppossite. foldr
和foldl
之间的最大区别在于运算符op
工作方式: foldl
是尾递归的,并且与相反的foldr
相比,从左到右应用运算符。
So, what you'd probably want is this: 因此,您可能想要的是:
foldl (\(currentFold, element) -> element:currentFold) [] [1,2,3,4,5]
Which could be beautified using flip
(as @mschmidt points out) 可以通过flip
来美化(如@mschmidt指出)
Recall that from foldr
equations: 回忆一下foldr
方程:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr op z [] = z
foldr op z (x:xs) = op x (foldr op z xs)
it will be slightly different: 会略有不同:
foldr (\(element, currentFold) -> element:currentFold) [] [1,2,3,4,5]
Which is the same as the one you posted: 与您发布的相同:
foldr (:) [] [1,2,3,4,5]
Another way to understand it, is: 另一种理解方式是:
foldr (:) [] [1..5]
means 手段
1 : (2 : (3 : (4 : (5 : []))))
while 而
foldl (:) [] [1..5]
means 手段
(((([] : 1) : 2) : 3) : 4) : 5
The latter makes no sense: is uses numbers as if they were lists. 后者是没有意义的:使用数字就好像它们是列表一样。 Further, every usage of :
changes the type of the output ( []
is a list, []:x
is a list-of-lists, ([]:x):y
is a list-of-lists-of-lists, and so on). 此外,每次使用:
改变输出的类型( []
是一个列表, []:x
是一个列表的清单, ([]:x):y
是一个列表的-列表-的-列表, 等等)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.