gpt4 book ai didi

haskell - 如何 foldr 和 zipWith ( :) work together?

转载 作者:行者123 更新时间:2023-12-04 18:18:56 26 4
gpt4 key购买 nike

我是 Haskell 的新手,我遇到了以下让我感到困惑的代码:

foldr (zipWith (:)) (repeat []) [[1,2,3],[4,5,6],[7,8,9,10]]

它产生以下结果,在玩弄它之后,我不完全确定为什么:
[[1,4,7],[2,5,8],[3,6,9]]

我的印象是 (:)将项目添加到列表中,然后 (repeat [])产生无穷无尽的空列表 [] ,以及 foldr接受一个函数、一个项目和一个列表,并通过将函数与结果一起连续应用于列表中的每个项目来压缩列表。

也就是说,我直观的理解了下面的代码是如何产生10的结果的:
foldr (+) 1 [2,3,4]

但是,我完全不知道为什么 foldr (zipWith (:)) (repeat [])获取一个列表列表并生成另一个列表列表,其中的项目按其原始内部索引分组。

任何解释都会有启发性。

最佳答案

这很简单。 foldr被定义为

foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)

因此,
foldr f z [a,b,c,...,n] = f a (f b (f c (...(f n z)...)))

或者,在这里,
foldr (zipWith (:)) (repeat []) [[1,2,3],[4,5,6],[7,8,9,10]]
=
zipWith (:) [1,2,3]
( foldr (zipWith (:)) (repeat []) [[4,5,6],[7,8,9,10]] )
=
...
=
zipWith (:) [1,2,3]
( zipWith (:) [4,5,6]
( zipWith (:) [7,8,9,10]
( foldr (zipWith (:)) (repeat []) [] )))
=
zipWith (:) [1,2,3]
( zipWith (:) [4,5,6]
( zipWith (:) [7,8,9,10]
( repeat [] )))
=
zipWith (:) [1,2,3]
( zipWith (:) [4,5,6]
( zipWith (:) [ 7, 8, 9,10]
[[],[],[],[],[],[],....] ))
=
zipWith (:) [1,2,3]
( zipWith (:) [ 4, 5, 6 ]
[[7],[8],[9],[10]] )
=
zipWith (:) [ 1 , 2 , 3 ]
[[4,7],[5,8],[6,9]]

就是这样。

(菜单上的下一个, traverse ZipList [[1,2,3],[4,5,6],[7,8,9,10]] ... :) 或者稍后。)

至于另一个例子,它是
foldr (+) 1 [2,3,4] 
= 2 + foldr (+) 1 [3,4]
= 2 + (3 + foldr (+) 1 [4])
= 2 + (3 + (4 + foldr (+) 1 []))
= 2 + (3 + (4 + 1))
= 2 + (3 + 5)
= 2 + 8
= 10

因为 +它的两个论点都是严格的。
zipWith两个参数都不严格, (:) 也不严格。 ,因此第一个序列应仅用作说明。实际的强制将以自上而下的顺序发生,而不是自下而上。例如,
> map (take 1) . take 1 $ zipWith (:) (1 : undefined) (repeat undefined)
[[1]]

完全按照
map (take 1) . take 1 $ zipWith (:) (1 : undefined) (repeat undefined)
=
map (take 1) . take 1 $ zipWith (:) (1 : undefined) (undefined : repeat undefined)
=
map (take 1) . take 1 $ (1 : undefined) : zipWith (:) undefined (repeat undefined)
=
map (take 1) $ (1 : undefined) : take 0 (zipWith (:) undefined (repeat undefined))
=
map (take 1) $ (1 : undefined) : []
=
map (take 1) [(1 : undefined)]
=
[take 1 (1 : undefined)]
=
[1 : take 0 undefined]
=
[1 : []]
=
[[1]]

关于haskell - 如何 foldr 和 zipWith ( :) work together?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55204856/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com