尝试在其上定义自定义数据类型和指定顺序。
我建议你像这样
data MPair a = MPair a a deriving (Show)
-- some helper to test
toTuple (MPair x y) = (x, y)
fromX x = MPair x x
instance (Eq a) => Eq (MPair a) where
(MPair a b) == (MPair c d) = (a == c) && (b == d)
-- This is not exactly the ordering you are looking for
-- But at this stage it should no be a pain to define
-- the required ordering, you just have to implement it below
instance (Ord a) => Ord (MPair a) where
compare p@(MPair a b) q@(MPair c d)
| p == q = EQ
| otherwise = case (compare a c, compare b d) of
(LT, _) -> LT
(_, LT) -> LT
_ -> GT
-- convert a list of tuple to a list or MPair.
fromListToMPair :: [(a,a)] -> [MPair a]
fromListToMPair [] = []
fromListToMPair ((a, b):xs) = (MPair a b) : fromListToMPair xs
-- the inverse of the previous one
fromMPairToList :: [MPair a] -> [(a,a)]
fromMPairToList [] = []
fromMPairToList ((MPair a b):xs) = (a, b) : fromMPairToList xs
-- A test case
testList = [(0,1),(0,3),(1,1),(1,3),(2,0),(2,1),(2,3),(4,1),(4,2)]
去 ghci 测试一下,
>>> fromMPairToList $ sort $ fromListToMPair testList
[(0,1),(0,3),(1,1),(1,3),(2,0),(2,1),(2,3),(4,1),(4,2)]
-- add a test to check the stability of your order.
>>> fromMPairToList $ sort $ sort $ fromListToMPair testList
[(0,1),(0,3),(1,1),(1,3),(2,0),(2,1),(2,3),(4,1),(4,2)]
-- ok this is stable
这不能满足您的要求,但这是我想说明的另一种方式。
事实上,我已经实现了对元组列表进行排序的经典规则。
现在我将尝试定义您的“排序”,然后我将重新定义 MPair 的 Ord 实例。像这样,
instance (Ord a, Num a) => Ord (MPair a) where
compare p@(MPair a b) q@(MPair c d)
| p == q = EQ
| check a b c d = LT
| otherwise = GT
where
pred x y = (abs (x - y)) < 2
check a b c d = pred a c && pred b d
然后当我重做 ghci 的测试时,
>>> fromMPairToList $ sort $ fromListToMPair testList
[(4,1),(4,2),(2,3),(2,0),(2,1),(1,3),(1,1),(0,3),(0,1)]
>>> fromMPairToList $ sort $ sort $ fromListToMPair testList
[(0,1),(0,3),(2,0),(1,1),(2,3),(1,3),(2,1),(4,1),(4,2)]
-- no this won't work, this is not an ordering, you cannot sort.
我意识到您的订单稳定性不满意,那么排序不是您所需要的。
最后,我想说这没有意义,因为您的标准没有在您的元组列表上定义顺序。您的标准是一个判别式,它将允许您创建两个数据子组。([标准 x 为真],[标准 x 不为真])。像往常一样对您的元组列表进行排序,并定义一个指定函数(基于您的标准),它将创建两个不同的组。
PS:也许您可以使用基于您的标准的函数在您的数据上建立订单,但我不知道如何实现它。