考虑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版本吗?我确实使用了相同的功能(break
,dropWhile
,isSpace
)。
我曾经非常惊讶GHC没有执行一些最简单的低级优化:
C vs Haskell Collatz conjecture speed comparison
但除了{-partain:Char.-}
位(这种情况下编译器的提示在这种情况下似乎没有用),words
代码似乎对于高级语言来说是不必要的。在这种情况下,它背后的原因是什么?
答案 0 :(得分:12)
这几乎是完全相同的代码。唯一的区别是,如果我们在每个呼叫之前执行dropWhile isSpace
或仅执行递归呼叫。两者都不比另一个复杂,但后者(Prelude)版本似乎更冗长,因为模式匹配不直接在函数中。
您可以观察差异(以及Prelude版本具有更好行为的原因),如下所示:
*Main> words " "
[]
*Main> words' " "
[""]
请注意,您可以使用QuickCheck
快速验证“改进”版本是否与原始版本相同。