【问题标题】:does this GADT actually have type role representational这个 GADT 是否真的具有类型角色代表性
【发布时间】:2014-08-05 00:43:43
【问题描述】:

此数据类型可以有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

安全吗?

【问题讨论】:

  • FWIW,是的,我想是的。但我对角色的内部知识知之甚少,无法真正提出令人信服的论点。您的示例似乎是当前角色系统不够表达的另一种情况。

标签: haskell gadt


【解决方案1】:

我认为仅存在转换是不够的。例如,下面的代码也让我可以在 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)

我还可以简单地定义一个类似于PrimeUnFoo 类型函数。

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

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

但是,由于理论上表示是依赖于实现的,我认为在 GHC 直接接受之前,您永远不会认为这是绝对安全的。

【讨论】:

  • 我不太确定“如果 l1 和 l2 具有相同的表示,HList l1 和 HList l2 具有相同的表示是很明显的”。我们可以写HCons :: (el ~ (e ': l)) => e -> HList l -> HList el。那么可能 ghc 为 el ~ (e ': l) 存储了一些引用原始 e, el, l 类型的东西,而不是当前在构造函数中的那些?
  • 即便如此,每个HCons 仍然具有与其他所有HCons 相同的表面表示,不是吗?所以如果eHList l 也有相同的表示,那么整个HCons 会。
  • 我认为关键在于':'[] 是必须不同的具体类型,因此不会混淆HConsHNil。我完全不确定如何精确地制定条件!
猜你喜欢
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 2020-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-02
  • 1970-01-01
相关资源
最近更新 更多