Haskell中的`unsafeCoerce`实现

The*_*nce 6 haskell ghc

我听说Haskell中的各种类型系统hacks(unsafePerformIO,模板Haskell,任意级别多态,......)可以用来强制不同类型,但我还没有看到显式实现.怎么做,至少在GHC?

chi*_*chi 13

在unsafePerformIO上

您可以使用unsafePerformIO创建顶级IORefs,即可变全局变量.如果向此添加多态,则会丢失类型安全性,如下所示:

myVar :: IORef a -- polymorphic ref!
myVar = unsafePerformIO $ newIORef undefined

coerce :: a -> b
coerce x = unsafePerformIO $ do
    writeIORef myVar x  -- write value of type a
    readIORef myVar     -- read value of type b
Run Code Online (Sandbox Code Playgroud)

基本上,类型的(非底部)值forall a. IORef a不应该存在.它的类型声明你可以将它用作你想要的类型的可变变量,所以你可以写它假装它有一种类型,然后从它读取假装它有另一种类型.

请注意,单态顶级IORefs不会导致类型不安全,因为您只能编写和读取相同类型的那些.

在其他人

较高等级是类型安全的,AFAIK.

我也不知道模板Haskell.

类型不安全的另一个来源是用户编写的Typeable实例,因为那些允许您声明自己的新数据类型实际上是Int并且成功用于cast强制值.

  • 我不相信使用Template Haskell引入类型不健全而不使用本身引入类型不健全的其他机制.虽然模板haskell`Exp`具有未知类型(并且可能是多态的!),但拼接总是在它们被展开时进行类型检查. (2认同)