您可以要求 GHC 的 desugarer 的输出,但是这也会对许多其他语法进行 desugar。
首先,我们将您的代码放在一个模块中Foo.hs
:
module Foo where
a = do x <- [3..4]
[1..2]
return (x, 42)
接下来,我们将要求 GHC 对其进行编译并在脱糖阶段后输出结果:
$ ghc -c Foo.hs -ddump-ds
输出可能看起来相当混乱,因为它是 Haskell 的一个变体,称为 Core,用作 GHC 的中间语言。但是,一旦习惯了它,阅读起来并不难。在其他一些定义的中间,我们找到了你的:
Foo.a :: [(GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)]
LclIdX
[]
Foo.a =
>>=_agg
@ GHC.Integer.Type.Integer
@ (GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)
(enumFromTo_ag7
(GHC.Integer.smallInteger 3) (GHC.Integer.smallInteger 4))
(\ (x_adf :: GHC.Integer.Type.Integer) ->
>>_agn
@ GHC.Integer.Type.Integer
@ (GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)
(enumFromTo_ags
(GHC.Integer.smallInteger 1) (GHC.Integer.smallInteger 2))
(return_aki
@ (GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)
(x_adf, GHC.Integer.smallInteger 42)))
核心不是很漂亮,但是在使用 GHC 时能够读取它非常有用,因为您可以在后期阶段阅读转储以了解 GHC 如何优化您的代码。
如果我们删除_xyz
重命名器添加的后缀,以及类型 applications@ Xyz
和对 的调用GHC.Integer.smallInteger
,并再次使运算符中缀,您将得到如下内容:
Foo.a :: [(GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)]
Foo.a = enumFromTo 3 4 >>= \x -> enumFromTo 1 2 >> return (x, 42)