OCaml是否有融合法

时间:2014-01-09 21:49:18

标签: haskell functional-programming ocaml

最近我正在阅读一些涉及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_leftfold_right且简单有效(例如,无论如何,我必须扫描整个列表并且不会停留在中间)。

但是,在大多数情况下,我将使用“模式匹配”编写显式递归代码。

另外我在github中读了很多OCaml项目,显式递归似乎很常见。

另外,我从未听说过OCaml的融合法。


我的问题是

  1. OCaml是否与上面Haskell中所示的模块化程序相同?
  2. OCaml是否也有融合法?
  3. 如果我想成为OCaml专业人士,我应该真正关心或学习Haskell的融合法吗?

2 个答案:

答案 0 :(得分:7)

由于副作用,在OCaml中实现Fusion并不像在Haskell中那样容易实现。如果你继续以与GHC融合它们相同的方式融合OCaml中的函数,那么你将得到非常不可预测的结果,并且副作用的发生顺序与编写程序的顺序不同。所以,不,就像你说的那样,OCaml没有“融合法则”。这并不意味着在OCaml中进行融合是不可能的,你只需要更加努力。

命令式语言的编译器有时会实现循环融合,这与Haskell中的融合具有类似的效果。 OCaml可以从循环融合中受益,但它是一个更加复杂的优化实现。

Fusion是Haskell中没有副作用的好处之一。它使某些优化更容易实现,并且它们可以为优化触发器提供更强有力的保证。

为了成为一名有效的OCaml程序员,我认为你不需要了解融合。

答案 1 :(得分:3)

在我个人看来,融合只是违背了OCaml的(未记录的)哲学:尽可能简化编译器,你所写的就是你所运行的。

一旦你了解Haskell(GHC)在更具挑战性的懒惰+纯粹设置下实现其速度所做的事情(或者是强制做什么),这听起来很无聊。但是许多工业OCaml用户购买这种简单性,因为它使编译器保持相当快,并且更容易预测OCaml中代码修改的性能变化。例如,Yaron Minsky最近在InfoQ中回答了同样的事情:link to the article

那就是说,我必须承认,有时候我想在OCaml中进行融合优化,特别是当我的巨大功能组合变慢时。我有时喜欢OCaml的简单性,有时候喜欢Haskell很酷的优化。

我的回答:

  1. 否。 OCaml stdlib没有函数组合运算符,我猜它是故意的。
  2. 否。如果你真的需要代码转换,你可以手动执行,或者使用camlp4或compiler-libs编写自己的转换hack。
  3. OCaml不执行融合,但了解融合的功能将有助于您优化OCaml代码。