为什么在 in 和 out 上具有相同数据结构(相同暗淡)的组合自递归函数不与其他递归一起内联?

Why aren't composed self-recursive functions with same data structure (same dims) on in and out inlined together with other recursions?

教程中https://markkarpov.com/tutorial/ghc-optimization-and-fusion.html#fusion-without-rewrite-rules是一个代码示例,不会被融合优化。

map0 :: (a -> b) -> [a] -> [b]
map0 _ []     = []
map0 f (x:xs) = f x : map0 f xs

foldr0 :: (a -> b -> b) -> b -> [a] -> b
foldr0 _ b []     = b
foldr0 f b (a:as) = foldr0 f (f a b) as

nofusion0 :: [Int] -> Int
nofusion0 = foldr0 (+) 0 . map0 sqr

sqr :: Int -> Int
sqr x = x * x

我的问题是:如果编译器可以轻松证明 map0 不会更改数据结构维度并推导 运行 上的所有内容,为什么函数 foldr0 (+) 0 . map0 sqr 不会自动内联到一个递归中从结构上到结构下?还是想不通,为什么这种代码不重写规则就不能自动优化

您是否知道任何具体原因,为什么不使用此优化?

谢谢。

我认为可以优化您的示例的最有前途的方法称为超级编译。有一篇关于惰性函数式语言超级编译的论文:https://www.microsoft.com/en-us/research/publication/supercompilation-by-evaluation/.

在论文的未来工作部分,作者声明:

The major barriers to the use of supercompilation in practice are code bloat and compilation time.

已经有人尝试将超级编译集成到 GHC 中,但尚未成功。我不知道所有细节,但有一个非常技术性的 GHC 维基页面:https://gitlab.haskell.org/ghc/ghc/-/wikis/supercompilation.