Why is this unsafeCoerce not unsafe?

  • A+

Some library use unsafeCoerce to temporarily satisfy constraint:

class Given a where given :: a  newtype Gift a r = Gift (Given a => r)  give :: forall a r. a -> (Given a => r) -> r give a k = unsafeCoerce (Gift k :: Gift a r) a 

(This example is from reflection package. singletons package also uses this trick.)

Why is this unsafeCoerce safe? Is there any official document which guarantee that Given a => r and a -> r have the same runtime representation in GHC?


No official document guarantees it. Ed Kmett is relying on what he knows about the inner workings of GHC. What he knows:

  1. In GHC Core, -> and => actually mean the same thing.
  2. Dictionaries for instances of single-method classes without superclasses are erased like newtypes—the dictionary is the method.

I've actually written a proposal to try to do this legitimately, but it's tricky to accommodate all the use cases properly.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: