GHC是否会在编译时化简非IO依赖表达式?含代码实例的技术问询
GHC对纯表达式的编译时化简
好问题!答案是:GHC确实会在编译时化简不依赖IO的纯表达式——具体取决于你开启的优化级别,在常用的优化模式下,你举的例子会被直接化简成Just 3。
具体到你的代码例子
对于main = print ( (+) <$> Just 1 <*> Just 2 ):
- 当使用优化编译(比如加上
-O或-O2参数)时,GHC的优化器会识别出(+) <$> Just 1 <*> Just 2是完全纯的计算,没有任何副作用或运行时依赖,会直接在编译阶段把它计算为Just 3。运行时程序会直接打印这个预计算好的常量,不会再去执行<$>和<*>的函数应用步骤。 - 如果是默认无优化编译(
-O0,这是GHC默认的编译模式,优先快速编译和调试友好),GHC会保留原始的表达式结构,运行时会一步步执行<$>(即fmap)和<*>的逻辑:先把(+)映射到Just 1上得到Just (+1),再用<*>把这个函数应用到Just 2上得到Just 3。
怎么验证?
你可以自己动手确认:
- 把代码保存为
Main.hs - 用优化编译并查看简化后的核心代码:
ghc -O -ddump-simpl Main.hs - 在输出的核心代码里,你会看到原本的
(+) <$> Just 1 <*> Just 2已经被替换成了Just 3。
补充说明
这种编译时对纯表达式的求值是GHC优化器的常规操作,叫做编译时求值(或常量折叠)。只要表达式满足:
- 没有任何IO或其他副作用
- 结果不依赖运行时的动态输入(比如命令行参数、用户输入等)
GHC都会尽可能在编译阶段把它计算好,减少运行时的开销。
内容的提问来源于stack exchange,提问作者Michiel Borkent
相关产品推荐
相关产品推荐

