维基百科写到
Hylomorphism
:
在[…]函数规划的一个同胚是递归的
函数,对应于一个变形的合成(其中
首先构建一组结果;也被称为“展开”)
通过一个亚同态(然后将这些结果折叠为最终返回
值)。将这两个递归计算融合为一个
然后是递归模式
避免构建中间数据
结构
。这是一个毁林的例子,一个计划
优化策略。
(我用粗体标记)
使用
recursion-schemes
图书馆
我写了一个非常简单的hylomorphism:
import Data.Functor.Foldable
main :: IO ()
main = putStrLn $ show $ hylosum 1000
hylosum :: Int -> Int
hylosum end = hylo alg coalg 1
where
-- Create list of Int's from 1 to n
coalg :: Int -> ListF Int Int
coalg n
| n > end = Nil
| otherwise = Cons n (n + 1)
-- Sum up a list of Int's
alg :: ListF Int Int -> Int
alg Nil = 0
alg (Cons a x) = a + x
在阴谋集团文件中,我指示GHC优化代码:
name: Hylo
version: 0.1.0.0
synopsis: Hylomorphisms and Deforestation
build-type: Simple
cabal-version: >=1.10
executable Hylo
main-is: Main.hs
ghc-options: -O2
build-depends: base >=4.10 && <4.11 , recursion-schemes
default-language: Haskell2010
使用stackage lts-10.0(GHC 8.2.2)编译
stack build
并与一起运行
stack exec Hylo -- +RTS -s
我得到:
500500
84,016 bytes allocated in the heap
3,408 bytes copied during GC
44,504 bytes maximum residency (1 sample(s))
25,128 bytes maximum slop
2 MB total memory in use (0 MB lost due to fragmentation)
现在我改变了
hylosum 1000
到
hylosum 1000000
(1000倍以上)我得到:
500000500000
16,664,864 bytes allocated in the heap
16,928 bytes copied during GC
15,756,232 bytes maximum residency (4 sample(s))
29,224 bytes maximum slop
18 MB total memory in use (0 MB lost due to fragmentation)
因此,堆使用率从84 KB上升到16664 KB。这比以前多了200倍。
因此,我认为,GHC不会像维基百科中提到的那样进行毁林/融合!
这并不奇怪:变形从左到右创建列表项
(从1到n)并且从右到左的相反方向的退化消耗项目
(从n到1)很难看出hylomorphism是如何工作的
不创建整个中间列表。
问题:
GHC是否能够实施森林砍伐?
如果
对
,我必须在我的代码或阴谋文件中更改什么?
如果
对
,它到底是如何工作的?
如果
不
,问题在哪里:在维基百科、GHC还是在图书馆?