【发布时间】:2016-09-04 00:10:53
【问题描述】:
我想创建一个数据类型,它可以采用长度为 2 或 3 的元组,并且应该包含派生 Num 和 Ord 的类型。然后,我想在我的类型类实例中对这个元组的长度进行模式匹配,以便我可以根据元组长度决定使用哪个函数。看看下面的不可编译的伪代码。至少有两个问题:
Dominates不是可派生类我不知道如何获取元组,例如调用
fitnesses,在实例中进行模式匹配时,将变量从数据类型中取出。
代码:
data Fits = I2 (Int, Int) | F2 (Float, Float) | I3 (Int, Int, Int) | F3 (Float, Float, Float)
data Ind = Ind { fitnesses :: Fits
, otherInfo :: String
} deriving (Dominates)
class Dominates a where
dominates :: a -> a -> bool
instance Dominates Ind where
dominates x@(_,_) y@(_,_) = x `dominates2` y -- takes two tuples of length 2
dominates x@(_,_,_) y@(_,_,_) = x `dominates3` y -- takes two tuples of length 3
更新:
data Ind = Ind { fitnesses :: Fits
, otherInfo :: String
}
instance Eq Ind where
(Ind{ fitnesses = I2 x@(a1,a2) }) == (Ind{ fitnesses = I2 y@(b1,b2) }) = indCmp2 x y == EQ
instance Ord Ind where
(Ind{ fitnesses = I2 x@(a1,a2) }) `compare` (Ind{ fitnesses = I2 y@(b1,b2) }) = indCmp2 x y
indCmp2 :: (Num a, Ord a) => (a, a) -> (a, a) -> Ordering
indCmp2 x y
| a0 < b0 = LT
| a0 > b0 = GT
-- Can assume (fst x) == (fst y) beneath
| a1 < b1 = LT
| a1 > b1 = GT
| a1 == b1 = EQ
where
a0 = fst x
a1 = snd x
b0 = fst y
b1 = snd y
这编译。如果我只想要Ord,为什么还要创建Eq 的实例?如果没有 Eq-instance,编译器会抱怨“没有 (Eq Ind) 的实例”。
【问题讨论】: