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

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

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

4

2 回答 2

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 会插入对适当实例字典的直接引用,而不是将其作为参数。然后,可以内联访问器,它基本上只是一个记录标签,并且您可以直接引用相应的函数。

于 2012-11-30T17:12:29.310 回答
-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 的。

于 2012-11-30T17:12:22.963 回答