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
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:
- In GHC Core,
=>actually mean the same thing.
- 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.