如何在不声明新数据的情况下更改类型为(String,Int)的元组的Ord实例?

Bil*_*ldo 5 sorting haskell

我正在尝试对type列表进行排序[(String, Int)]。默认情况下,它是按字符串排序,然后按整数排序(如果字符串相等)。我希望它是相反的-首先,比较Ints,然后如果相等,则比较Strings。另外,我不想切换到[(Int, String)]

我通过定义一个实例找到了一种方法,但是它仅适用于我自己不想使用的数据类型。

Wil*_*sem 13

您可以使用sortBy :: (a -> a -> Ordering) -> [a] -> [a]

import Data.List(sortBy)
import Data.Ord(comparing)
import Data.Tuple(swap)

orderSwap :: (Ord a, Ord b) => [(a, b)] -> [(a, b)]
orderSwap = sortBy (comparing swap)
Run Code Online (Sandbox Code Playgroud)

或搭配sortOn :: Ord b => (a -> b) -> [a] -> [a]

import Data.List(sortOn)
import Data.Ord(comparing)
import Data.Tuple(swap)

orderSwap :: (Ord a, Ord b) => [(a, b)] -> [(a, b)]
orderSwap = sortOn swap
Run Code Online (Sandbox Code Playgroud)

或者我们可以执行两次交换并对中间结果进行排序:

import Data.Tuple(swap)

orderSwap :: (Ord a, Ord b) => [(a, b)] -> [(a, b)]
orderSwap = map swap . sort . map swap
Run Code Online (Sandbox Code Playgroud)

当然,这不是“标准订购”。如果您要定义的固有顺序不同于已定义实例派生的固有顺序,则应定义自己的类型。

例如:

newtype MyType = MyType (String, Int) deriving Eq

instance Ord MyType where
    compare (MyType a) (MyType b) = comparing swap a b
Run Code Online (Sandbox Code Playgroud)

  • 或者只是`sortOn swap`。 (4认同)
  • 您的第一个也可以拼写为“ sortBy(比较交换)”。 (2认同)