此数据类型可以包含type role HCons' representational representational
,允许使用coerce
添加或删除应用于元素的新类型,而无需遍历列表。
data HNil' = HNil'
data HCons' a b = HCons' a b
然而,这些列表的语法不如具有以下GADT
的语法好data HList (l::[*]) where
HNil :: HList '[]
HCons :: e -> HList l -> HList (e ': l)
我有一个convert between these two representations课程,Prime (HList [a,b]) ~ HCons' a (HCons' b HNil')
。该课程是否
coerceHList :: Coercible (Prime a) (Prime b) => HList a -> HList b
coerceHList = unsafeCoerce
安全?
答案 0 :(得分:2)
我不认为转换的存在就足够了。例如,以下内容还允许我在GADT和一对强制类型之间进行转换,但直接胁迫GADT肯定不安全:
newtype Age = Age Int
data Foo a where
I :: Bool -> Int -> Foo Int
A :: Age -> Bool -> Foo Age
class ConvFoo a where
toFoo :: (Bool, a) -> Foo a
fromFoo :: Foo a -> (Bool, a)
instance ConvFoo Int where
toFoo (b, i) = I b i
fromFoo (I b i) = (b, i)
instance ConvFoo Age where
toFoo (b, a) = A a b
fromFoo (A a b) = (b, a)
我还可以简单地定义类似于UnFoo
的{{1}}类型函数。
我认为两个示例之间的主要区别在于,我的Prime
和Age
具有相同的表示形式,而在您的Int
和'[]
中#don 39; t具有相同的表示。
因此,正如您在标题中所建议的,e':l
类型角色具有代表性,因此仍然可以说l
和HList l1
{如果HList l2
和l1
具有相同的表示,则{1}}具有相同的表示形式。
然而,由于在理论上表示是依赖于实现的,我认为在GHC直接接受之前,您可以认为这绝对安全。