【问题标题】:Why isn't the Prelude's words function written more simply?为什么 Prelude 的文字功能写的不简单?
【发布时间】:2013-05-03 00:20:05
【问题描述】:

考虑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'

我认为这有与优化相关的原因。问题是:我期望编译器应该像其 Prelude 版本一样优化 words' 函数是错误的吗?我确实使用了相同的功能(breakdropWhileisSpace)。

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

C vs Haskell Collatz conjecture speed comparison

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

【问题讨论】:

  • 顺便说一句,我认为{-partain:Char.-} 位只不过是一个注释掉的模块名称。据谷歌称,前一段时间有人在 GHC 工作。我猜那只是他签署了他的 cmets。
  • 哦,我以为它可能对编译器有一些影响。与 Partian 家伙的精彩接球!

标签: haskell optimization compiler-construction


【解决方案1】:

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

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

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

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

【讨论】:

  • 嗯,我不认为我的版本比原版更好,但这就是重点;对我来说,唯一的区别似乎是冗长。
  • 我再次查看了Prelude 和其他一些核心库,我必须说,在函数定义中,冗长实际上非常罕见(并且可能通过像您描述的那样的情况来解释)。最初的问题标题夸大了:)。
猜你喜欢
  • 2013-06-09
  • 2019-08-23
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多