为什么这个 unsafeCoerce 不是不安全的?

Why is this unsafeCoerce not unsafe?

一些库使用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

(此示例来自 reflection 包。 singletons 包也使用了这个技巧。)

为什么 unsafeCoerce 安全? 是否有任何官方文件保证 Given a => ra -> r 在 GHC 中具有相同的运行时表示?

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

  1. 在GHC Core中,->=>实际上是同一个意思。
  2. 没有 super类 的单一方法 类 实例的字典像新类型一样被删除——字典 方法。

我实际上已经写了一个 proposal 来尝试合法地做到这一点,但是要正确地适应所有用例是很棘手的。