用于将多态数据结构提升为GADT的类型的运行时比较

时间:2010-10-30 22:51:56

标签: haskell gadt

假设我们定义了一个GADT来比较类型:

data EQT a b where
  Witness :: EQT a a

是否可以使用以下类型签名声明函数 eqt

eqt :: (Typeable a, Typeable b) => a -> b -> Maybe (EQT a b)

... eqt xy 评估 Just Witness 如果 typeOf x == typeOf y ---否则没有

函数 eqt 可以将普通的多态数据结构提升为GADT。

1 个答案:

答案 0 :(得分:11)

是的。这是一种方式:

首先是类型相等类型。

data EQ :: * -> * -> * where
  Refl :: EQ a a  -- is an old traditional name for this constructor
  deriving Typeable

请注意,它本身可以成为Typeable的一个实例。这是关键。 现在我只需要把手放在我需要的Refl上,就像这样。

refl :: a -> EQ a a
refl _ = Refl

现在我可以尝试将(Refl :: Eq a a)变成某种类型(Eq a b) 通过使用Data.Typeable的强制转换运算符。那将在a和b时起作用 是平等的!

eq :: (Typeable a, Typeable b) => a -> b -> Maybe (EQ a b)
eq a _ = cast (refl a)

努力工作已经完成。

可以在Data.Witness库中找到有关此主题的更多变体, 但是Data.Typeable转换操作符就是这项工作所需要的。它的 当然,作弊,但安全包装作弊。