最近,我正在读一些有关Haskell的函数式编程书籍。
例如,Haskell似乎很喜欢“模块化程序”,
f :: (Integer,Integer) -> Integer
f = sum . map sq . filter . odd . between即使相同的函数可以编写成
f' (m, n) = go m
where go m | m > n = 0
| otherwise = go (m + 1) + if odd m then sq m else 0“融合定律”也很受欢迎和使用(http://www.cs.ox.ac.uk/ralf.hinze/publications/IFL10.pdf)
我不是OCaml专家,但如果可能的话,我会使用fold_left或fold_right (例如,无论如何,我必须扫描整个列表,不会停留在中间)。
但是,在大多数情况下,我将使用“模式匹配”编写显式递归代码。
此外,我在github中阅读了相当多的OCaml项目,而显式递归似乎是非常常见的。
此外,我从未听说过OCaml的融合定律。
我的问题是
发布于 2014-01-09 23:10:00
由于副作用,在OCaml中实现融合并不像在Haskell那样容易。如果您继续以与GHC融合相同的方式融合OCaml中的函数,那么您将得到非常不可预测的结果,以及与您编写程序的顺序不同的副作用。所以,不,正如你所说的,OCaml没有“融合定律”。这并不意味着不可能在OCaml中进行融合,您只需要更加努力地工作。
命令式语言的编译器有时实现循环融合,这与Haskell中的融合效果类似。OCaml可以从循环融合中获益,但这是一个需要实现的更复杂的优化。
融合是一个很好的例子,说明在Haskell没有副作用的好处之一。它使某些优化更易于实现,并且它们可以为何时触发优化提供更强的保证。
我认为,为了成为一名有效的OCaml程序员,您不需要对融合了解那么多。
发布于 2014-01-10 03:26:00
在我个人看来,融合完全违背了OCaml(无文档)的理念:使编译器尽可能简单,您所编写的就是运行的。
这听起来很无聊,一旦你了解了Haskell(GHC)在更具挑战性的lazy+pure设置下做了什么(或强迫做)来达到它的速度。但是许多工业OCaml用户都购买这种简单性,因为它使编译器保持了相当快的速度,并且更容易在OCaml中预测代码修改的性能变化。例如,Yaron最近在InfoQ:链接到文章中回答了同样的问题。
尽管如此,我必须承认,有时我希望在OCaml中进行类似于优化的融合,特别是当我庞大的函数组合变得更慢时。我有时喜欢OCaml的简单性,有时喜欢Haskell的酷优化。
我的回答是:
https://stackoverflow.com/questions/21031920
复制相似问题