- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
维基百科写到 Hylomorphism :
In [...] functional programming a hylomorphism is a recursive function, corresponding to the composition of an anamorphism (which first builds a set of results; also known as 'unfolding') followed by a catamorphism (which then folds these results into a final return value). Fusion of these two recursive computations into a single recursive pattern then avoids building the intermediate data structure. This is an example of deforestation, a program optimization strategy.
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
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
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)
最佳答案
数据结构实际上被融合了,但生成的程序不是尾递归的。优化后的代码基本上是这样的(看不到 Cons
或 Nil
):
h n | n > end = 0
| otherwise = n + h (n+1)
h (n+1)
递归,然后将结果添加到
n
.在递归调用期间,值
n
必须保持存储在某处,因此我们观察到内存使用量增加为
end
增加。
-- with BangPatterns
h n !acc | n > end = acc
| otherwise = h (n+1) (n + acc)
hylosum
,调用
(+)
发生在
alg
, 我们将其替换为对由
hylo
建立的延续的调用。 .
alg :: ListF Int (Int -> Int) -> Int -> Int
alg Nil acc = acc
alg (Cons n go) !acc = go (n + acc)
关于haskell - 同态中的森林砍伐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49135351/
我真的很喜欢以通用方式处理变形/变形的想法,但在我看来它有一个显着的性能缺陷: 假设我们想要以分类方式使用树结构 - 使用通用 catamorphism function 来描述不同的折叠: newt
我是一名优秀的程序员,十分优秀!