考虑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.-}位(对于这种情况,对于IMO而言,编译器的提示似乎不是很有帮助),对于高级语言而言,words代码似乎不必要地膨胀。在这种情况下背后的原因是什么?

最佳答案

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

您可以像这样观察差异(以及为什么Prelude版本具有更好的行为):

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

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

关于haskell - 为什么not't the Prelude's的单词功能写得更简单?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16446274/

10-09 09:16