考虑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.-}
位(对于这种情况,对于IMO而言,编译器的提示似乎不是很有帮助),对于高级语言而言,words
代码似乎不必要地膨胀。在这种情况下背后的原因是什么? 最佳答案
这几乎是完全相同的代码。唯一的区别是,我们是在每次调用之前还是仅在递归调用之前执行dropWhile isSpace
。两者都不比另一个更复杂,但是后者(Prelude)版本似乎更冗长,因为模式匹配并不直接在函数中。
您可以像这样观察差异(以及为什么Prelude版本具有更好的行为):
*Main> words " "
[]
*Main> words' " "
[""]
请注意,您可以使用
QuickCheck
快速验证“改进的”版本是否与原始版本相同。关于haskell - 为什么not't the Prelude's的单词功能写得更简单?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16446274/