题
有人知道函数的Haskell“ foldr”使用的步骤?
GHCI命令窗口:
foldr (\x y -> 2*x + y) 4 [5,6,7]
评估后的结果:
40
关于这个的步骤
Prelude> foldr (\x y -> 2*x + y) 4 [5,6,7]
6 * 2 + (7 * 2 + 4)
12 + 18 = 30
5 * 2 + 30 = 40 v
解决方案
foldr的一个定义是:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f acc [] = acc
foldr f acc (x:xs) = f x (foldr f acc xs)
这 Wikibook在Haskell上 在foldr上有一个不错的图形(也在其他折叠上):
: f
/ \ / \
a : foldr f acc a f
/ \ -------------> / \
b : b f
/ \ / \
c [] c acc
IE a : b : c : []
(这只是 [a, b, c]
) f a (f b (f c acc))
(再次取自Wikibook)。
因此,您的示例被评估为 let f = (\x y -> 2*x + y) in f 5 (f 6 (f 7 4))
(仅出于简洁而放松)。
其他提示
您实际上可以轻松地自己可视化它:
import Text.Printf
showOp f = f (printf "(%s op %s)") "0" ["1","2","3"]
然后
Main> showOp foldr
"(1 op (2 op (3 op 0)))"
Main> showOp foldl
"(((0 op 1) op 2) op 3)"
Main> showOp scanl
["0","(0 op 1)","((0 op 1) op 2)","(((0 op 1) op 2) op 3)"]
这本来应该是对德尔南的言论的评论,但太言语了……
Yoon,您可以与 lambdabot
在#haskell irc上(例如 http://webchat.freenode.net/ )。她具有简单的反射能力,因此您可以输入毫无意义的字母,例如
Yoon: > foldr (\x y -> 2*x + y) o [a,b,c,d]
lamdabot: 2 * a + (2 * b + (2 * c + (2 * d + o)))
这说明了评估的内容,但是正如Edka指出的那样,您可以从Say中获得评估顺序
Yoon: > reverse (scanr (\x y -> 2*x + y) o [a,b,c,d])
lambdabot: [o,2 * d + o,2 * c + (2 * d + o),2 * b + (2 * c + (2 * d + o)),2 * a + (2 * b + (2 * c + (2 * d + o)))
我记得在上面写一些好课程 foldr
, foldl
, scanr
, scanl
和这个聪明的设备。
不隶属于 StackOverflow