我有以下类型:
data Person a = {name :: String, age :: Int, injury :: Injury a}
data Injury a = Physical a | Mental a
我试图创建一个将伤害提升到一个人的实体的功能:
liftInjury :: Person a -> Injury a -> Person a
liftInjury person inj = person {injury = int}
class Hospital i where
admit :: Person a -> i -> Person a
instance Hospital (Injury a) where
admin person inj = liftInjury person inj -- ERROR
错误:
Couldn't match type ‘a’ with ‘a1’
‘a’ is a rigid type variable bound by
the instance declaration
这是否是因为编译器不知道a
中被拒绝的liftInjury
与a
中的instance Hospital (Injury a) ...
相同?
对此最佳解决方案是什么?
答案 0 :(得分:1)
您可以使用多参数类型类来解决此问题,这样您就可以对Person
的类型和Injury
的类型设置约束:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
class Hospital i p where
admit :: Person p -> i -> Person p
instance Hospital (Injury a) a where
admit person inj = liftInjury person inj
将Person
的类型参数添加到类定义中,可以在instance
声明中对其进行约束,这样可以确保Person
的类型参数和Injury
是一样的。
更简单的选择是更改Hospital
以获取伤害的类型参数而不是伤害类型本身:
class Hospital a where
admit :: Person a -> Injury a -> Person a
...但我想你系统的其余部分会排除该选项。