Does GHC removes polymorphic indirection when possible?
ghc, haskell, polymorphism
Solution
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.
Problem
``` 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?