查找出现次数最多的元素的函数

Function to find the most frequent element

我正在尝试编写一个函数,该函数 returns 是列表中出现次数最多的元素。到目前为止我有以下

task :: Eq a => [a] -> a
task xs  = (map ((\l@(x:xs) -> (x,length l)) (occur (sort xs)))) 

occur 是一个函数,它接受一个列表和 returns 一个对列表,其中包含输入列表的元素以及它们出现的次数。因此,例如对于列表 [1,1,2,3,3] ,输出将是 [(1,2),(2,1),(3,2)].

但是,我收到一些与 map 的参数相关的错误。谁能告诉我我做错了什么?

地图将每个项目映射到另一个项目,所以这里 \l 是一个二元组,如 (1,2)(2, 1)(3, 2)。因此使用 length l 没有多大意义,因为 length :: Foldable f => f a -> Int 总是 return 一个二元组:这是因为只有二元组的第二部分被使用在可折叠。但是我们一开始就不需要length

你需要的是一个可以根据二元组的第二项检索最大值的函数。我们可以使用 maximumOn :: Ord b => (a -> b) -> [a] -> a from the exta package,或者我们可以实现自己的函数来计算项目列表的最大值。

这样的函数应该是这样的:

maximumSnd :: Ord b => [(a, b)] -> (a, b)
maximumSnd [] = error "Empty list"
maximumSnd (x:xs) = go xs x
    where go [] m = m
          go (x@(xa, xb):xs) (ya, yb)
              | xb > yb = go … …  -- (1)
              | otherwise = go … …  -- (2)

这里 (1) 应该实现,以便我们进行递归调用,但使用 x 作为我们迄今为止发现的新最大值。 (2) 应该使用 相同 到目前为止的最大值进行递归调用。

一旦我们实现了 maxSnd 函数,我们就可以将此函数用作辅助函数:

task :: Eq a => [a] -> (a, Int)
task xs  = <strong>maxSnd</strong> (occur xs)

或者我们可以使用 fst :: (a, b) -> a 来检索二元组的第一项:

task :: Eq a => [a] -> a
task xs  = <strong>(fst . maxSnd)</strong> (occur xs)

如果有两个字符具有最大元素数,maximumSnd 将 return 出现在列表中的第一个字符。