list - 理解实现 foldr 和 foldl 的函数

标签 list haskell fold function-definition

有些情况下我不明白foldrfoldl 是如何在函数中使用的。

这里有几个例子,然后我解释为什么我不理解它们:

-- Two implementation of filter and map
map' f = foldr (\x acc -> (f x):acc) [] 
map'' f xs = foldl (\acc x -> acc ++ [(f x)]) [] xs 

filter' f xs = foldr(\x acc -> if(f x) then x:acc else acc) [] xs 
filter'' f  = foldl(\acc x -> if(f x) then acc++[x] else acc) [] 

为什么 map'' 使用 xs 而不是 map'map' 不应该也需要列表理解公式的列表吗?

filter'filter'' 的情况相同。

这是一个在排序序列中插入元素的实现:

insert e [] = [e]
insert e (x:xs)
     | e > x = x: insert e xs
     | otherwise = e:x:xs
sortInsertion xs = foldr insert [] xs
sortInsertion'' xs = foldl (flip insert) [] xs

为什么 insert 的参数在 sortInsertion ([] xs) 中翻转([] xs)(空列表和列表)比较 insert 的定义(e []) (元素和空列表)

最佳答案

Why does map'' makes the use of xs but non map'? Shouldn't map' need a list for the list comprehension formula as well? Same case for filter' vs filter''.

这称为“eta-reduction”,它是一种省略冗余参数名称的常用方法(“无点样式”)。基本上只要你有一个函数,它的主体只是函数对其参数的应用,你就可以减少参数:

add :: Int -> Int -> Int
add x y = x + y

-- “To add x and y, call (+) on x and y.”
add :: (Int) -> (Int) -> (Int)
add x y = ((+) x) y

-- “To add x, call (+) on x.”
add :: (Int) -> (Int -> Int)
add x = (+) x

-- “To add, call (+).”
add :: (Int -> Int -> Int)
add = (+)

更准确地说,如果你有 f x = g x 其中 x 没有出现在 g 中,那么你可以写成 f = g.

一个常见的错误是想知道为什么 f x = g 。 h x 不能写成 f = g 。 h.它不符合该模式,因为 (.) 运算符是 f 主体中的顶级表达式:它实际上是 f x = (.) g (h x)。您可以将其写为 f x = (((.) g) . h) x 然后将其简化为 f = (.) g 。 hf = fmap g 。 h-> 使用 Functor 实例,但这被认为不是非常可读。

Why are the argument for insert flipped in sortInsertion

foldrfoldl 的函数参数参数顺序不同:

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b

或者,使用更冗长的类型变量名:

foldr
  :: (Foldable container)
  => (element -> accumulator -> accumulator)
  -> accumulator -> container element -> accumulator

foldl
  :: (Foldable container)
  => (accumulator -> element -> accumulator)
  -> accumulator -> container element -> accumulator

这只是折叠关联方向的助记符:

foldr f z [a, b, c, d]
==
f a (f b (f c (f d z)))  -- accumulator on the right (second argument)

foldl f z [a, b, c, d]
==
f (f (f (f z a) b) c) d  -- accumulator on the left (first argument)

关于list - 理解实现 foldr 和 foldl 的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66521982/

相关文章:

ocaml - 使用 List.fold_right 将数字插入排序列表

algorithm - 什么是高效实现图像渲染的纯函数数据结构?

list - 将map与具有多个参数的函数一起使用

scala - 折叠左单行中的类型推断?

haskell - 在 Haskell 中只想要一个答案

haskell - 应用仿函数作为幺半群仿函数

python - 列表索引必须是整数,而不是 str

c# - 将字符串列表存储在 ListView 的单独列中 (C#)

Python:列表到整数到单个数字?

python - 如何并排垂直打印列表?