使用记录语法提升到数据构造函数?

时间:2017-03-28 15:55:13

标签: haskell

我有以下类型:

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中被拒绝的liftInjurya中的instance Hospital (Injury a) ...相同?

对此最佳解决方案是什么?

1 个答案:

答案 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

...但我想你系统的其余部分会排除该选项。