首先,我正在阅读的真实世界Haskell表示永远不会使用foldl
而是使用foldl'
.所以我相信它.
但我对什么时候使用foldr
vs. 朦胧foldl'
.虽然我可以看到他们如何以不同的方式摆放在我面前的结构,但是当"哪个更好"时,我太愚蠢了.我想在我看来似乎并不重要,因为它们都产生相同的答案(不是吗?).事实上,我以前使用这个结构的经验来自Ruby inject
和Clojure reduce
,它们似乎没有"左"和"右"版本.(附带问题:他们使用哪个版本?)
任何有助于像我这样的智能挑战的洞察力都会非常感激!
此问题中 myAny函数的代码使用foldr.当谓词满足时,它会停止处理无限列表.
我用foldl重写了它:
myAny :: (a -> Bool) -> [a] -> Bool
myAny p list = foldl step False list
where
step acc item = p item || acc
Run Code Online (Sandbox Code Playgroud)
(请注意,步骤函数的参数已正确反转.)
但是,它不再停止处理无限列表.
我试图在Apocalisp的答案中跟踪函数的执行情况:
myAny even [1..]
foldl step False [1..]
step (foldl step False [2..]) 1
even 1 || (foldl step False [2..])
False || (foldl step False [2..])
foldl step False [2..]
step (foldl step False [3..]) 2
even 2 || (foldl step False [3..])
True || (foldl …
Run Code Online (Sandbox Code Playgroud) 在Real World Haskell中,第4章.函数式编程
用foldr写foldl:
-- file: ch04/Fold.hs
myFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl f z xs = foldr step id xs z
where step x g a = g (f a x)
Run Code Online (Sandbox Code Playgroud)
上面的代码让我很困惑,有人打电话给dps用一个有意义的名字重写它,使它更清晰:
myFoldl stepL zeroL xs = (foldr stepR id xs) zeroL
where stepR lastL accR accInitL = accR (stepL accInitL lastL)
Run Code Online (Sandbox Code Playgroud)
其他人,Jef G,通过提供一个例子并逐步展示基础机制,做得非常出色:
myFoldl (+) 0 [1, 2, 3]
= (foldR step id [1, 2, …
Run Code Online (Sandbox Code Playgroud) 循环的方向foldl
和foldr
方向之间的区别是什么?我认为他们所做的不同,而不只是方向?