GHC是否在可能的情况下删除了多态间接?

时间:2012-11-30 16:52:00

标签: haskell polymorphism ghc

showInt :: Int -> String
showInt x = show x

上面的代码是否调用show传递Int字典,还是直接调用Show Int实例上声明的函数?

我的意思是,GHC是否会尽可能从生成的代码中删除多态间接?

2 个答案:

答案 0 :(得分:10)

是。这是使用GHC 7.4.2生成的核心:

Foo.showInt :: GHC.Types.Int -> GHC.Base.String
[... attributes omitted ...]
Foo.showInt = GHC.Show.$fShowInt_$cshow

如您所见,它只是对GHC.Show.$fShowInt_$cshow的直接引用。

比较我们删除类型签名时会发生什么,以便改为使用推断类型Show a => a -> String

Foo.showInt
  :: forall a_aop. GHC.Show.Show a_aop => a_aop -> GHC.Base.String
[... attributes omitted ...]
Foo.showInt =
  \ (@ a_aot) ($dShow_aou :: GHC.Show.Show a_aot) (x_a9Z :: a_aot) ->
    GHC.Show.show @ a_aot $dShow_aou x_a9Z

这里,它需要一个字典参数$dShow_aou,它使用访问器函数GHC.Show.show来查看 在将结果函数应用于参数x_a9Z之前,使用此字典中的相应函数。

在第一种情况下,至少在概念上会发生的事情是,由于具体类型是已知的,GHC会插入对相应实例字典的直接引用,而不是将其作为参数。然后,访问器,基本上只是一个记录标签,可以内联,你就离开了 直接参考适当的功能。

答案 1 :(得分:-7)

GHC不这样做。想一下新创建的可读性类型:

type Vector = (Float, Float)

如果GHC会从以下函数中删除多态性:

(!+!) :: Vector -> Vector -> Vector
(x1, y1) !+! (x2, y2) = (x1 + x2, y1 + y2)

该类型将成为:

(!+!) :: (Float, Float) -> (Float, Float) -> (Float, Float)

虽然该功能专门用于Vector。