showInt :: Int -> String
showInt x = show x
Does the above code calls show
passing the Int
dictionary or does it calls directly the function declared on Show Int
instance?
I mean, does GHC removes polymorphic indirection from generated code when possible?
Yes. This is the generated core using GHC 7.4.2:
Foo.showInt :: GHC.Types.Int -> GHC.Base.String
[... attributes omitted ...]
Foo.showInt = GHC.Show.$fShowInt_$cshow
As you can see, it's just a direct reference to GHC.Show.$fShowInt_$cshow
.
Compare with what happens if we remove the type signature so that the inferred type Show a => a -> String
is used instead:
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
Here, it takes a dictionary argument $dShow_aou
and it uses the accessor function GHC.Show.show
to look
up the appropriate function from this dictionary before applying the resulting function to the argument x_a9Z
.
What happens in the first case, at least conceptually, is that since the concrete type is known, GHC inserts a direct reference to the appropriate instance dictionary rather than taking it as an argument. Then, the accessor, which is basically just a record label, can be inlined and you're left with a direct reference to the appropriate function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With