按int对('String ',int)的列表排序(Haskell)

wfsdck30  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(164)

我是Haskell的新手,所以我还在学习很多东西。我得到了一个名字和年龄的列表,我需要按字母顺序和年龄的升序对它们进行排序。我设法按字母顺序对列表进行排序,但我不确定如何使用年龄值进行排序。我可以在下面的代码中更改什么?谢谢您的帮助。

qsort :: (Ord a) => [a] -> [a]
-- check to see if the list is empty
qsort [] = []
qsort [x] = [x] -- Single element list is always sorted
qsort [x, y] = [(min x y), (max x y)]
-- x is the pivot, left quicksort returns smaller sorted and right quicksort bigger sorted
qsort (x:xs) =
  qsort [a | a <- xs, a <= x] ++ [x] ++ qsort [a | a <- xs, a > x]

people=[("Steve",20),("Smith",31),("Kris",19),("Beth",21)]

main = do
  print(qsort people) -- sort alphabetically
hgc7kmma

hgc7kmma1#

首先,让我们稍微简化一下你的函数。[x][x, y]都是冗余的:它们完全被(x:xs)捕获了,所以我们把它们去掉。

qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) =
  qsort [a | a <- xs, a <= x] ++ [x] ++ qsort [a | a <- xs, a > x]

现在,我们假设列表的类型和排序依据的类型是相同的,我们将它们都称为a,我们将它们改为两种类型:a将是我们列表的类型,b将是我们要排序的类型。只有b必须满足Ord,我们需要一个函数将a转换为b,这样我们就可以对列表进行排序。这是我们想要的类型

qsort :: (Ord b) => (a -> b) -> [a] -> [a]

我们的基本情况基本上是相同的,只是我们忽略了函数参数。

qsort _ [] = []

在我们的递归示例中,我们通过应用函数f :: a -> b和 * then * 使用<=>进行比较。

qsort f (x:xs) =
    qsort f [a | a <- xs, f a <= f x] ++ [x] ++ qsort f [a | a <- xs, f a > f x]

现在我们可以按照任何类型的Ord进行排序。

-- Note: (fst :: (a, b) -> a) is in Prelude
print (qsort fst people)

或第二个

-- Note: (snd :: (a, b) -> b) is in Prelude
print (qsort snd people)

两者都按其自然排序顺序。
如果我们想按相反的顺序排序(降序而不是升序),我们可以使用Down作为函数;如果我们想按某个复杂的顺序排序,我们总是可以使用newtype pattern

相关问题