如何按字符串排序自定义类型

Ker*_*ukk 2 sorting haskell list

我怎样才能按名字对动物进行分类?名称由String值表示.

data Animal = Cat String | Dog String | Fox String deriving (Show)

testAnimals = [(Dog "c"),(Fox "a"),(Cat "b")]

sortAnimalsByName :: [Animal] -> [Animal]
sortAnimalsByName animals = undefined
Run Code Online (Sandbox Code Playgroud)

查询:

sortAnimalsByName testAnimals
Run Code Online (Sandbox Code Playgroud)

应该返回:

[(Fox "a"),(Cat "b"),(Dog "c")]
Run Code Online (Sandbox Code Playgroud)

我认为,功能sort :: Ord a => [a] -> [a]Data.List应使用,但如何?

Wil*_*sem 8

首先,您最好定义一个animalName函数:

animalName :: Animal -> String
animalName (Cat n) = n
animalName (Dog n) = n
animalName (Fox n) = n
Run Code Online (Sandbox Code Playgroud)

只需使用sortBy其中比较简直是compareonanimalName:

import Data.Function(on)
import Data.List(sortBy)

sortAnimalsByName :: [Animal] -> [Animal]
sortAnimalsByName = sortBy (compare `on` animalName)
Run Code Online (Sandbox Code Playgroud)

或者你可以 - 像@JonPurdy建议的那样使用comparing它基本上和以下相同on compare:

import Data.Ord(comparing)

sortAnimalsByName :: [Animal] -> [Animal]
sortAnimalsByName = sortBy (comparing animalName)
Run Code Online (Sandbox Code Playgroud)

甚至更短:

import Data.List(sortOn)

sortAnimalsByName :: [Animal] -> [Animal]
sortAnimalsByName = sortOn animalName
Run Code Online (Sandbox Code Playgroud)

animalName如果使用记录语法,还可以省略定义:

--omitting the `animalName` function
data Animal = Cat { animalName :: String} |
              Dog { animalName :: String} |
              Fox { animalName :: String} deriving (Show)
Run Code Online (Sandbox Code Playgroud)