在 Haskell 中测试 (Eq a) 的类型

Testing a type for (Eq a) in Haskell

我想看看我是否可以实现一些关于类型是否实现 Eq 的分支。

尝试一下:

data HTrue
data HFalse

type family Eq1 (a :: *) where
  Eq1 (Eq x) = HTrue
  Eq1 a = HFalse

您会注意到我在代码中放入了 (a :: *)。那是因为如果我不这样做,代码会编译,但会生成 Eq1 作为约束,而我实际上希望它是一个封闭类型族。

有什么方法可以让它发挥作用吗?

在不同的上下文中可见的实例集也是不同的,所以任何这样的函数都是非常危险的。说真的,不要那样做。考虑像这样定义两个新类型:

module EqTest (HasEq, NoEq, hasEq, noEq, fromEq)
newtype HasEq a = HasEq a
newtype NoEq a = NoEq a
hasEq :: Eq a => a -> HasEq a
hasEq = HasEq
noEq :: a -> NoEq a
noEq = NoEq
class FromEq c where fromEq :: c a -> a
instance FromEq HasEq where fromEq (HasEq a) = a
instance FromEq NoEq where fromEq (NoEq a) = a

并且不导出构造函数。您必须始终指定要使用的版本,但这比依赖 class 个实例要好。