我有一个类型Id a
,我试图防止意外强制转换,例如将Id Double
转换为 Id Int
。
如果我正确理解类型的角色,以下代码不应该编译。
{-# LANGUAGE RoleAnnotations #-}
import Data.Coerce (coerce)
type role Id nominal
newtype Id a = Id String
badKey :: Id Int
badKey = coerce (Id "I point to a Double" :: Id Double)
不幸的是,它确实会:
Prelude> :load Id.hs
[1 of 1] Compiling Main ( Id.hs, interpreted )
Ok, one module loaded.
*Main> :type badKey
badKey :: Id Int
我对类型角色有什么不理解的吗?
Id
中的a
是一个幽灵变量,对内部实际值没有影响。如果你有newtype Id a = Id a
,那么强制转换就会失败。 - lehinstype role
的目的是使其不成为这种情况。这个问题在问为什么它没有起作用。 - Joseph Sible-Reinstate Monica