关于haskell:为什么Prelude的单词功能不是更简单?

Why isn't the Prelude's words function written more simply?

考虑words前奏函数,它非常简单,可以用以下方式编写:

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

然而,我注意到它最初的序曲代码似乎要少得多…自然:

1
2
3
4
5
6
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'函数和它的前奏版本?我确实使用了相同的函数(breakdropWhileisSpace

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

C与Haskell-Colatz推测速度比较

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


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

您可以这样观察差异(以及为什么前奏曲版本有更好的表现):

1
2
3
4
*Main> words"   "
[]
*Main> words'"    "
[""]

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