最近我正在阅读一些涉及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的融合法。
我的问题是
答案 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很酷的优化。
我的回答: