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:
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 -> Stringis used instead:Here, it takes a dictionary argument
$dShow_aouand it uses the accessor functionGHC.Show.showto lookup 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.