假设我们定义了一个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。
答案 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转换操作符就是这项工作所需要的。它的 当然,作弊,但安全包装作弊。