所以我正在阅读"Learn You A Haskell",在chapter about modules中,有一个名为search的函数的定义,它检查列表是否包含子列表。
my_search :: Eq a => [a] -> [a] -> Bool
my_search sub l =
let
len = length sub
eqTest = (\acc x -> if take len x == sub then True else acc)
in foldl eqTest False $ tails l
现在,我想知道为什么不使用本章前面提到的foldl'
,并且运行得更快:
my_search' :: Eq a => [a] -> [a] -> Bool
my_search' sub l =
let
len = length sub
eqTest = (\acc x -> if take len x == sub then True else acc)
in foldl' eqTest False $ tails l
*Main> my_search [10^6,10^6+1] [1..10^7]
True
(7.76 secs, 3,197,168,792 bytes)
*Main> my_search' [10^6,10^6+1] [1..10^7]
True
(4.53 secs, 2,964,986,352 bytes)
更好的是,通过小调整,我们可以使用foldr
,它也可以通过短路处理无限列表。
my_searchr :: Eq a => [a] -> [a] -> Bool
my_searchr sub l =
let
len = length sub
eqTest = (\x acc -> if take len x == sub then True else acc)
in foldr eqTest False $ tails l
查看isInfixOf
的{{3}},我看到它已使用any
实施,后者使用foldr
。
我是否遗漏了某些内容,或者在这种情况下使用foldr
是否更好?
答案 0 :(得分:4)
我是否遗漏了某些内容,或者在这种情况下使用foldr更好?
不,你没有遗漏任何东西,你的分析是正确的; foldl
在这里不是正确的工具,甚至foldl'
都是可疑的;手头的任务固有地受益于懒惰,因此应该使用foldr
。