【问题标题】:Is it possible to write a generall derived instance for a data type in haskell?是否可以在 haskell 中为数据类型编写通用派生实例?
【发布时间】:2019-02-12 15:09:53
【问题描述】:

我需要在两个 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 的单个部分,在实际代码中它将是一个 Integer,我需要为其编写四个案例。有没有办法概括这一点,所以我可以在一个案例中编写它? 如果我比较两个 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

【问题讨论】:

  • 这可能不是lawful Eq instance。假设您允许树的消费者查看除节点权重之外的任何内容,您就违反了“替代性”定律。为什么需要这些 Eq 和 Ord 实例?寻找替代方法来实现您心中的任何目标。

标签: haskell derived-instances


【解决方案1】:

为所欲为,先写一个更通用的版本(即多态版本)getWeight,只需要重写类型签名即可:

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

然后您可以执行以下操作(在 importing 来自 Data.Functionon 函数之后 - 我还按照 @FyodorSolkin 的建议重写了它们以使它们变得免费)

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

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

【讨论】:

  • 我认为将它们写成无点会更干净,例如compare = compare `on` getWeight
  • 好点@FyodorSoikin,不知道我是怎么错过的。我会编辑并给你信用:)
  • 更好:compare = comparing getWeight.
  • 看起来不错@Alec,实际上我以前从未遇到过comparing。事实证明,我可以在这里回答哪些问题实际上有助于我自己了解更多有关 Haskell 的信息 :)
猜你喜欢
  • 2015-07-18
  • 2011-11-05
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
  • 2016-01-12
相关资源
最近更新 更多