2013-05-08 6 views
14

Prelude関数をwordsと考えてください。それは本当に簡単で、1は次のようにそれを書くことができます:Preludeのwords関数はなぜ簡単に書かれていないのですか?

words' :: String -> [String] 
words' [] = [] 
words' str = before : words' (dropWhile isSpace after) where 
    (before, after) = break isSpace str 

はしかし、私は自然な...元のプレリュードコードがはるかに少ないようだということに気づい:

words     :: String -> [String] 
words s     = case dropWhile {-partain:Char.-}isSpace s of 
           "" -> [] 
           s' -> w : words s'' 
             where (w, s'') = 
              break {-partain:Char.-}isSpace s' 

私があることを前提としてい最適化に関連する理由問題は、コンパイラがPreludeバージョンと同様にwords'関数を最適化することを期待するのは間違っていますか?私は同じ機能(break,dropWhile,isSpace)を使用しました。

私は一度GHCは、最も単純な低レベルの最適化の一部を実行しなかったことを非常に驚いた

:で非常に有用でいないようだ

C vs Haskell Collatz conjecture speed comparison

が、脇{-partain:Char.-}ビットのために(コンパイラこのヒントをこの状況IMO)wordsコードは、高水準言語のために不必要に肥大しているようです。この場合、その背後にある理由は何ですか?

+5

「{-partain:Char .-}」ビットはコメントアウトされたモジュール名以上のものではないと思います。 Googleによると、姓がパルテン(Partain)の人はしばらく前にGHCで働いていた。私は彼が彼のコメントに署名していることを推測している。 – hammar

+0

ああ、コンパイラに多少の影響があったかもしれないと思った。 Partainの男といいキャッチ! – ljedrz

+2

それは分裂するでしょう。 – augustss

答えて

12

これはほぼ同じコードです。唯一の違いは、毎回または再帰呼び出しの前にdropWhile isSpaceを実行している場合です。いずれも他のものよりも複雑ではありませんが、後者(Prelude)バージョンは、パターンマッチングが直接関数内にないため、より冗長であるようです。

あなたがそうのような違い(そしてなぜプレリュードバージョンがより良い行動を持っている)を観察することができます:あなたの「改善」のバージョンがQuickCheckを使用してオリジナルと同じである場合は、すぐに確認することができます

*Main> words " " 
[] 
*Main> words' "  " 
[""] 

注意。

+0

さて、私のバージョンは元のバージョンよりも優れているとは思えませんが、それがポイントです。唯一の違いは冗長であるように見えました。 – ljedrz

+0

私は 'Prelude'と他のいくつかのコアライブラリをもう一度見てきました。そして、私は冗長は実際には関数定義ではまれであると言わなければなりません。最初の質問のタイトルは過言であった:)。 – ljedrz

関連する問題