在Haskell中测试(等式a)的类型

在Haskell中测试(等式a)的类型,haskell,type-families,Haskell,Type Families,我试图看看我是否可以实现一些分支,这些分支取决于类型是否实现Eq 以下是一个尝试: data HTrue data HFalse type family Eq1 (a :: *) where Eq1 (Eq x) = HTrue Eq1 a = HFalse 您会注意到我在代码中添加了(a::*)。这是因为如果我不这样做,代码会编译,但会生成Eq1作为约束,而我实际上希望它是一个封闭类型族 有什么方法可以让它工作吗?在不同的上下文中可见的实例集也是不同的,因此任何这样的函数都是非常危

我试图看看我是否可以实现一些分支,这些分支取决于类型是否实现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

并且不要导出构造函数。你必须总是指定你想要使用哪个版本,但是这比依赖类实例要好。

这个应用程序是什么?考虑TESTQUAL:(可键入A,EQ A,B型,EQ B)=A->B->BOOL TESTQUAL XY=FROM。您还可以执行诸如“如果是Ord,则对列表进行排序”之类的开放类型类(如
Eq
)和单独编译来处理此类型族。例如,假设模块
A
定义了类型
T
,以及
f::Eq1 T->HFalse;fx=x
,然后模块
B
导入
A
并添加
实例(Eq T)
?什么时候应该检测到类型错误?正如chi所说的,这不起作用,而且它必然不起作用。你的选择是放弃这一思路,或者把你自己的
Eq
写成
class Eq a(b::Bool)| a->b;实例Eq Int True;实例Eq Bool True;实例Eq SomeType False