为什么这种不安全的Coerce不安全?

Hog*_*ama 15 haskell ghc

一些库用于unsafeCoerce临时满足约束:

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
Run Code Online (Sandbox Code Playgroud)

(这个例子来自反射包. 单圈包也使用这个技巧.)

为什么这样unsafeCoerce安全?是否有这保证任何正式文件Given a => r,并a -> r在GHC相同的运行时表示?

dfe*_*uer 15

没有官方文件保证.Ed Kmett依赖于他对GHC内部运作的了解.他所知道的:

  1. 在GHC核心,->并且=>实际上意味着同样的事情.
  2. 没有超类的单方法类实例的字典像newtypes一样被删除 - 字典就是方法.

我实际上写了一个试图合法地做到这一点的提议,但是正确地适应所有用例是很棘手的.