这个GADT实际上是否具有代表性的类型角色

aav*_*ogt 13 haskell gadt

此数据类型可以具有type role HCons' representational representational,允许使用coerce添加或删除应用于元素的新类型,而无需遍历列表.

data HNil' = HNil'
data HCons' a b = HCons' a b
Run Code Online (Sandbox Code Playgroud)

但是,这些列表的语法不如具有以下GADT的语法好

data HList (l::[*]) where
    HNil  :: HList '[]
    HCons :: e -> HList l -> HList (e ': l)
Run Code Online (Sandbox Code Playgroud)

我有一个类在这两个表示之间进行转换,这样Prime (HList [a,b]) ~ HCons' a (HCons' b HNil').该课程是否成功?

coerceHList :: Coercible (Prime a) (Prime b) => HList a -> HList b
coerceHList = unsafeCoerce
Run Code Online (Sandbox Code Playgroud)

安全?

GS *_*ica 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)
Run Code Online (Sandbox Code Playgroud)

我还可以简单地定义一个UnFoo类似于 的类型函数Prime

我认为这两个示例之间的主要区别在于,在我的AgeInt中确实具有相同的表示,而在您的'[]和中e':l没有相同的表示。

因此,正如您在标题中所建议的那样,仍然有理由说l具有角色代表性类型,因为很明显,如果HList l1HList l2具有相同的表示,则l1l2具有相同的表示。

然而,由于理论上表示是依赖于实现的,所以我认为在 GHC 直接接受它之前你不能认为这是绝对安全的。