我有一个函数(频率),它计算列表中每个不同值出现在该列表中的次数。例如,
frequency "ababca"
应该返回:
[(3, 'a'), (2, 'b'), (1, 'c')].
这很好但现在我需要使用此函数使用列表列表中的第一个元素对列表进行排序。
results :: [Party ] -> [(Int, Party)]
results xs = ??? frequency (sort xs) ???
所需输出的示例:
[(1, "Green"), (2, "Red"), (3, "Blue")]
以上不起作用,我不知道我能做什么。
使用常规'排序'
先谢谢你。
答案 0 :(得分:8)
import Data.Function (on)
import Data.List (sortBy)
results xs = sortBy (compare `on` fst) (frequency xs)
-- or, if you prefer
results xs = sort (frequency xs)
指向on
,sortBy
,compare
,fst
的文档的链接。
区别在于sort
按每对的第一个元素的升序排序,打破与对的第二个元素的打破中断,而sortBy (compare `on` fst)
显式只查看第一个元素每一对。
答案 1 :(得分:2)
如果您只能使用sort
而不是sortBy
(出于某种原因!),那么您需要确保这些项的类型是Ord
的实例。碰巧的是,所有元组(最大为15)都有Ord
个实例,前提是 all 元组中的位置也有Ord
个实例。
您提供的(1, "Green"), (2, "Red"), (3, "Blue")]
示例应该排序正常(尽管相反),因为Int
和String
都有Ord
个实例。
但是,在代码段中,您还提到了Party
类型而没有实际说明它是什么。如果它不仅仅是String之类的别名,您可能必须为它定义一个Ord
实例,以满足元组的内置Ord实例。
您可以在声明类型时使用deriving
为Haskell创建实例
data Party = P1 | P2 | P3 | P4 -- e.g.
deriving (Eq,Ord)
或自己声明:
instance Ord Party where
-- you don't care about the ordering of the party values
compare a b = EQ
但是,正如dave4420所说,只使用sortBy
会好得多,所以除非你有特殊的理由不这样做,否则我会这样做(即它是一个有限制的课程作业)。