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

Thi*_*gri 7 polymorphism haskell ghc

showInt :: Int -> String
showInt x = show x
Run Code Online (Sandbox Code Playgroud)

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

我的意思是,GHC是否在可能的情况下从生成的代码中删除了多态间接?

ham*_*mar 10

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

Foo.showInt :: GHC.Types.Int -> GHC.Base.String
[... attributes omitted ...]
Foo.showInt = GHC.Show.$fShowInt_$cshow
Run Code Online (Sandbox Code Playgroud)

如您所见,它只是一个直接参考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
Run Code Online (Sandbox Code Playgroud)

这里,它需要一个字典参数$dShow_aou,它使用访问器函数GHC.Show.show在将结果函数应用于参数之前从该字典中查找适当的函数x_a9Z.

在第一种情况下,至少在概念上会发生的事情是,由于具体类型是已知的,GHC会插入对相应实例字典的直接引用,而不是将其作为参数.然后,访问器(基本上只是一个记录标签)可以内联,并且您可以直接引用相应的函数.