我想测试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获胜的明显案例吗?
我想在f#中编写一个尾递归文件夹,以利用尾递归优化并了解有关函数式编程的更多信息。
我写了一个尾递归折叠,和一个不是尾递归的文件夹。我以为可以通过反转馈给该函数的列表来获取尾递归文件夹,然后对其调用我的尾递归文件夹,但是由于该功能应采用的顺序不同,因此无法正常工作。
let rec tail_recurse_foldl(list: List<'a>, func:('b -> 'a -> 'b), acc: 'b) =
match list with
| [] -> acc
| [x] -> func acc x
| x :: xs -> tail_recurse_foldl(xs, func, func acc x)
Run Code Online (Sandbox Code Playgroud)
和非尾递归文件夹
let rec foldr(list: List<'a>, func:('a -> 'b -> 'b), acc: 'b) =
match list with
| [] -> acc
| [x] -> func x acc
| x::xs -> func x (foldr(xs, func, acc))
Run Code Online (Sandbox Code Playgroud)