Haskell 将多态数据结构提升到GADT中的类型的运行时比较

Haskell 将多态数据结构提升到GADT中的类型的运行时比较,haskell,gadt,Haskell,Gadt,假设我们定义了用于比较类型的GADT: data EQT a b where Witness :: EQT a a 然后是否可以使用以下类型签名声明函数eqt: eqt :: (Typeable a, Typeable b) => a -> b -> Maybe (EQT a b) …如果typeOf x==typeOf y,则eqt x y的计算结果为仅见证,否则为无 函数eqt可以将普通多态数据结构提升到GADT中。是的。这里有一个方法: 首先是类型相等类型 dat

假设我们定义了用于比较类型的GADT:

data EQT a b where
  Witness :: EQT a a
然后是否可以使用以下类型签名声明函数eqt

eqt :: (Typeable a, Typeable b) => a -> b -> Maybe (EQT a b)
…如果typeOf x==typeOf y,则eqt x y的计算结果为仅见证,否则为


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

是的。这里有一个方法:

首先是类型相等类型

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::eqa)转换成某种类型(eqa-b) 通过使用Data.Typeable的cast运算符。这将在a和b同时起作用 我们是平等的

eq :: (Typeable a, Typeable b) => a -> b -> Maybe (EQ a b)
eq a _ = cast (refl a)
艰苦的工作已经完成了

有关此主题的更多变体,请参见Data.Witness库, 但是这个工作只需要Data.Typeable cast操作符。它是
当然是作弊,但安全包装作弊。

只要没有人在某个东西上生成错误的
数据,安全包装。可键入的
实例。(
导出可键入的
总是安全的。)请注意,现在
eq
数据中可用。可键入的
模块如下所示