相关疑难解决方法(0)

foldl与具有无限列表的foldr行为

此问题中 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)

haskell combinators lazy-evaluation fold

115
推荐指数
3
解决办法
2万
查看次数

foldl是尾递归的,那么foldr如何比foldl运行得更快呢?

我想测试foldl vs foldr.从我所看到的,你应该使用foldl over foldr,因为尾部递归优化.

这是有道理的.但是,运行此测试后,我很困惑:

foldr(使用时间命令时需要0.057秒):

a::a -> [a] -> [a]
a x = ([x] ++ )

main = putStrLn(show ( sum (foldr a [] [0.. 100000])))
Run Code Online (Sandbox Code Playgroud)

foldl(使用time命令时需要0.089s):

b::[b] -> b -> [b]
b xs = ( ++ xs). (\y->[y])

main = putStrLn(show ( sum (foldl b [] [0.. 100000])))
Run Code Online (Sandbox Code Playgroud)

很明显,这个例子很简单,但我很困惑为什么foldr击败foldl.这不应该是foldl获胜的明显案例吗?

optimization haskell tail-recursion combinators fold

68
推荐指数
4
解决办法
2万
查看次数