2016-05-04 17 views
1

"Learn You A Haskell"chapter about modulesには、リストにサブリストが含まれているかどうかを調べるsearchという名前の関数の定義があります。haskellでfoldlの代わりにfoldrを使う

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'を使用しない理由は今、私は疑問に思う、と速く走る:小さな調整で、私たちも扱うことができるfoldrを使用することができ、

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) 

いっそ短絡による無限リスト。 isInfixOfdefinitionを見ると

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 

、私はfoldrを使用する、anyで実装されます参照してください。

この場合、何か不足していますか、それともfoldrを使用する方が良いですか?

+1

これはおそらく、著者はパフォーマンスについては気にしなかったが、ここではモジュールについて...? – Carsten

+0

さまざまなフォールドの違いについての詳細:https://wiki.haskell.org/Foldr_Foldl_Foldl ' – ErikR

+1

@ ErikR。ありがとう、私はwikiを読んで、AFAIU、 'foldl'はほとんど使用されていません。それは長いリスト上の固有の低性能を有するため、 – dimid

答えて

4

この場合、foldrを使用した方が良いですか?

いいえ、あなたは何も欠けておらず、あなたの分析は正しいです。 foldlはここでは適切なツールではなく、さらにfoldl'は疑わしいです。手元の作業は本質的に怠惰の恩恵を受けるため、foldrを使用する必要があります。

+0

おかげで、「そうfoldlのは使用すべきである。」、もしかして'foldr'? – dimid

+0

もちろん...: - ] –

関連する問題