是否可以在haskell中为数据类型编写通用的派生实例?

时间:2019-02-12 15:09:54

标签: haskell derived-instances

我需要在两个Htree之间进行比较,因此我实现了我自己的比较函数,该函数与sortBy一起使用,但是我想实现Eq和Ord类的派生实例,但需要涵盖所有可能情况的案例数量组合使其不切实际。

data Htree a b = Leaf a b
         | Branch a (Htree a b) (Htree a b)
          deriving (Show)

instance (Eq a) => Eq (Htree a b) where 

     (Leaf weight1 _ ) == (Leaf weight2 _) = weight1 == weight2
     (Branch weight1 _ _) == (Leaf weight2 _) = weight1 == weight2
     (Leaf weight1 _ ) == (Branch weight2 _ _) = weight1 == weight2
     (Branch weight1 _ _) == (Branch weight2 _ _) = weight1 == weight2

如您所见,我只想比较Htree的单个部分,它在实际代码中将是一个整数,因此我需要为此编写四个案例。有没有一种方法可以概括这一点,以便我可以在一种情况下编写? 如果我比较两个Htree,则比较它们的整数部分?

我目前用来比较两个htree的是:

comparison :: Htree Integer (Maybe Char) -> Htree Integer (Maybe Char) -> 
Ordering
comparison w1 w2 = if(getWeight(w1) > getWeight(w2)) then GT
               else if(getWeight(w1) < getWeight(w2)) then LT
               else EQ

其中getWeight定义为:

getWeight :: Htree Integer (Maybe Char) -> Integer
getWeight(Leaf weight _) = weight
getWeight(Branch weight _ _) = weight

1 个答案:

答案 0 :(得分:7)

要执行所需的操作,请首先编写getWeight的更通用的版本(即,多态版本),只需重写类型签名即可:

getWeight :: Htree a b -> a
getWeight(Leaf weight _) = weight
getWeight(Branch weight _ _) = weight

然后,您可以执行以下操作(在importon使用Data.Function函数之后-我也按照@FyodorSolkin的建议重写它们以使其指向自由状态)

instance (Eq a) => Eq (Htree a b) where
    (==) = (==) `on` getWeight

instance (Ord a) => Ord (Htree a b) where
    compare = compare `on` getWeight