我有类似的类型
data Fruit = Apple Date
| Balana Date
| Orange Date
f = [Apple 2020-01-01 ,Apple 2020-02-01
,Balana 2020-01-01 ,Balana 2020-02-01]
getDate:: Fruit -> Date
getDate (Apple x) = x
getDate (Balana x) = x
getDate (Orange x) = x
当按CCD_ 2字段对列表CCD_。
instance Ord Fruit where
compare f1 f2 = compare (getDate f1) (getDate f2)
但是,问题是,如何设置规则来订购Apple 2020-01-01
和Balance 2020-01-01
?
如果我想先对日期进行排序,如果不同类型的水果的date
相同,我会先订购Apple
,然后订购Balance
,再订购Orange
?
[Apple 2020-01-01, Balance 2020-01-01, Apple 2020-02-01 ,Balana 2020-02-01]
谢谢!
您可以使用一些不同的方法:
最直接的不是你想要什么,而是用来了解
data Fruit = Apple Date
| Balana Date
| Orange Date
deriving (Eq, Ord)
这会为您键入创建自动订单,但在这种情况下,它会先比较水果,然后比较Date
。。。这正是你想要的相反。
因此,我们需要手动定义一个f
0实例。
-- This get the date from fruit
getDate :: Fruit -> Date
getDate (Apple x) = x
getDate (Balana x) = x
getDate (Orange x) = x
-- This function compares the fruit with no date.
fruitOrder :: Fruit -> Fruit -> Ordering
fruitOrder (Apple _) (Apple _) = EQ
fruitOrder (Apple _) _ = LT
fruitOrder (Orange _) (Orange _) = EQ
fruitOrder (Orange _) _ = GT
fruitOrder (Balana _) (Balana _) = EQ
fruitOrder (Balana _) (Apple _) = GT
fruitOrder (Balana _) (Orange _) = LT
-- Your ordering is a combination of both
instance Ord Fruit where
compare f g = comparing getDate f g <> fruitOrder f g
-- | |- This returns the first not EQ value or EQ if both are equal
-- |- comparing func x y == compare (func y) (func y)
不同的建模
现在,您可能正在以一种非惯用的方式对类型进行建模。如果你的所有物品都有一个日期,那么你应该将你的类型编码为成对的,如下所示
-- This is an alternative representation. You have Fruit types ordered as written
data FruitType = Apple | Banana | Orange deriving (Eq, Ord)
-- A fruit is a Date and a FruitType, this is Record syntax
-- you can think of it as C's structs or Python's dataclasses.
data Fruit = Fruit {getDate :: Date, getType :: FruitType} deriving (Eq, Ord)
-- The derived order is lexicographic, meaning they are ordered by the first field, and then by the second field
例如,该程序使用建议的类型按预期订购您的列表
import Data.List
type Date = String -- For the sake of example
-- This is an alternative representation. You have Fruit types ordered as written
data FruitType = Apple | Banana | Orange deriving (Show, Eq, Ord)
-- A fruit is a Date and a FruitType, this is Record syntax
-- you can think of it as C's structs of Python's dataclasses.
data Fruit = Fruit {getDate :: Date, getType :: FruitType} deriving (Show, Eq, Ord)
f = [ Fruit "2020-01-01" Apple
, Fruit "2020-02-01" Apple
, Fruit "2020-01-01" Banana
, Fruit "2020-02-01" Banana]
main = print $ sort f