拥有以下数据类型和类型类:
data T1 a
data T2 a
data T3 a
class TC1 a where
m1 :: T1 a
class TC2 a where
m2 :: T2 a
class TC3 a where
m3 :: T3 a
我想写一个像这样的函数:
dummy :: (TC1 a | TC2 a | TC3 a) => a
意思是' a'应该 TC1
或 TC2
或 TC3
作为类型类约束。例如,这些函数应该键入check:
dummyInt :: T2 Int
dummyInt = dummy
dummyChar :: T1 Char
dummyChar = dummy
我的第一个想法是创建一个没有方法的虚拟类型类:
class TC a
instance TC (T1 a)
instance TC (T2 a)
instance TC (T3 a)
现在,使用此签名正确检查上述示例:
dummy :: TC a => a
但是,首先,我在这里滥用类型课吗?这种方法的缺陷是什么?
否则,如果这没关系,可能会因为更多的类型变量和类型类而变得混乱。有没有那么笨重的方法呢?
我尝试了这些类型的家庭:
data family TF a
data instance TF a = T1 a | T2 a | T3 a
class Dummy a where
dummy :: TF a
instance Dummy Int where
dummy = undefined
...
即使我有权更改类型构造函数,我也不知道,我认为我仍然需要为数据族包装新的构造函数,最终它并没有包含它们。最终简化了代码。
其次,尽管将m1
,m2
和m3
统一到单个类型类中的单个方法并摆脱{{1} },TC1
和TC2
类型类,然后我必须在定义新实例时使用显式数据构造函数。理想情况下,我希望我可以使用这样的同义词系列:
TC3