部分应用程序和子表达式仅取决于函数参数的子集

pyo*_*yon 5 haskell scope

我是否应该期望Haskell编译器足够智能以优化以下定义:

h x y = p (m x) (n y)
Run Code Online (Sandbox Code Playgroud)

进入这样的事情:

h x = let z = m x in \y -> p z (n y)
Run Code Online (Sandbox Code Playgroud)

?如果m评估费用昂贵,这可能很方便,我用h以下方式定义:

main = print $ map (h 2) hugeList
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 8

但是,如果m评价便宜,但其结果存储成本高昂?说m x = [x .. ]并且p需要遍历该列表的不同前缀,具体取决于n y.如果然后m 2共享map (h 2) hugeList,并且任何列表元素都需要长前缀,那么即使所有后续元素只需要列表的第一个元素来返回结果,也会有很大的内存需求.

因此,自动共享m x也可能是一种悲观,因此您不应期望所有编译器自动共享它.

通常,编译器很难决定共享是有益的还是有害的,因此您应该在您真正想要的地方明确共享.(尽管如此,预计编译器会引入共享,即使有时你不想要它.)