使用foldr进行搜索而不是haskell中的foldl

时间:2016-05-04 06:34:34

标签: haskell

所以我正在阅读"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是否更好?

1 个答案:

答案 0 :(得分:4)

  

我是否遗漏了某些内容,或者在这种情况下使用foldr更好?

不,你没有遗漏任何东西,你的分析是正确的; foldl在这里不是正确的工具,甚至foldl'都是可疑的;手头的任务固有地受益于懒惰,因此应该使用foldr