简体   繁体   English

如何在操作符中使用foldl

[英]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): foldlfoldr的类型签名在函数参数中稍有不同(它们具有切换的参数):

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. foldrfoldl之间的最大区别在于运算符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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM