我听说Haskell中的各种类型的系统攻击(unsafePerformIO
,模板Haskell,任意级别多态,......)可以用来强制不同类型,但我还没有看到显式实现。怎么做,至少在GHC?
答案 0 :(得分:13)
您可以使用unsafePerformIO
创建顶级IORef
,即可变全局变量。如果向此添加多态,则会丢失类型安全性,如下所示:
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
基本上,类型forall a. IORef a
的(非底部)值不应存在。它的类型声明你可以将它用作你想要的类型的可变变量,所以你可以写它假装它有一种类型,然后从它读取假装它有另一种类型。
请注意,单态顶级IORef
不会导致类型不安全,因为您只能编写和读取相同类型的那些。
更高等级是类型安全的,AFAIK。
我也不知道模板Haskell。
另一种类型不安全的来源是用户编写的Typeable
实例,因为那些允许您声明自己的新数据类型实际上是Int
并成功使用cast
来强制值。< / p>