为什么Prelude的单词功能不是更简单?

时间:2013-05-08 17:02:11

标签: haskell optimization compiler-construction

考虑words Prelude功能;它非常简单,可以用以下方式编写它:

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

然而,我注意到它的原始Prelude代码似乎更少......自然:

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

我认为存在与优化相关的原因。问题是:我错误地认为编译器应该优化words'函数以及它的Prelude版本吗?我确实使用了相同的功能(breakdropWhileisSpace)。

我曾经非常惊讶GHC没有执行一些最简单的低级优化:

C vs Haskell Collatz conjecture speed comparison

但除了{-partain:Char.-}位(这种情况下编译器的提示在这种情况下似乎没有用),words代码似乎对于高级语言来说是不必要的。在这种情况下,它背后的原因是什么?

1 个答案:

答案 0 :(得分:12)

这几乎是完全相同的代码。唯一的区别是,如果我们在每个呼叫之前执行dropWhile isSpace或仅执行递归呼叫。两者都不比另一个复杂,但后者(Prelude)版本似乎更冗长,因为模式匹配不直接在函数中。

您可以观察差异(以及Prelude版本具有更好行为的原因),如下所示:

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

请注意,您可以使用QuickCheck快速验证“改进”版本是否与原始版本相同。