理解单态与多态Core表达式
我想了解简单的算术表达式是如何编译到 GHC 9.0.1 Core 中的
为此,我隔离了相同的声明,
f = x y -> sqrt x + y
并将其编译为两种不同的类型:
f :: Double -> Double -> Double
f :: Floating a => a -> a -> a
导致这些非常不同的野兽:
(x [Dmd=<S,1*U(U)>] :: Double) (y [Dmd=<S,1*U(U)>] :: Double) ->
case x of { D# x ->
case y of { D# y -> D# (+## (sqrtDouble# x) y) }
}
在单态情况下和
(@a)
($dFloating_a22t [Dmd=<S(S(S(C(C(S))LLLLLL)LLL)LLLLLLLLLLLLLLLLLLLLLL),U(1*U(1*U(1*C1(C1(U)),A,A,A,A,A,A),A,A,A),A,A,A,1*C1(U),A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A)>]
:: Floating a)
(eta_B0 :: a)
(eta_B1 :: a) ->
+ @a
($p1Fractional @a ($p1Floating @a $dFloating_a22t))
(sqrt @a $dFloating_a22t eta_B0)
eta_B1
在多态之一。
除了需求/严格注释(这些Dmd=...东西),这值得一个单独的问题,我很想了解两个结果表达式的不同形状。在单态情况下,我们进行嵌套大小写匹配,但在另一种情况下,我们只看到用类型变量 ( @a) 和约束 ($p1Fractional等)注释的运算符
我想我应该补充一点,上面的输出是通过在预先存在的 CoreToDo 列表的最后运行的自定义插件传递获得的,所以在脱糖等之后(这是我对这个主题的全部了解)
是否存在 GHC 阶段,其中这两个编译版本在结构上相同?