我是Haskell的新手,我只是想编写一个列表理解来计算列表中每个不同值的频率,但是我在最后一部分遇到了麻烦.
到目前为止我有这个:
frequency :: Eq a => [a] -> [(Int,a)]
frequency list = [(count y list,y) | y <- rmdups ]
Run Code Online (Sandbox Code Playgroud)
涉及rmdups的最后一部分有问题.
count函数接受一个字符,然后是一个字符列表,并告诉你该字符出现的频率,代码如下.
count :: Eq a => a -> [a] -> Int
count x [] = 0
count x (y:ys) | x==y = 1+(count x ys)
| otherwise = count x ys
Run Code Online (Sandbox Code Playgroud)
先感谢您.
Tox*_*ris 14
在计算频率时,您还可以使用关联数组/有限映射将列表元素中的关联存储到其计数中:
import Data.Map (fromListWith, toList)
frequency :: (Ord a) => [a] -> [(a, Int)]
frequency xs = toList (fromListWith (+) [(x, 1) | x <- xs])
Run Code Online (Sandbox Code Playgroud)
用法示例:
> frequency "hello world"
[(' ',1),('d',1),('e',1),('h',1),('l',3),('o',2),('r',1),('w',1)]
Run Code Online (Sandbox Code Playgroud)
请参阅fromListWith和的文档toList.
The*_*est 11
我不得不使用Ord而不是Eq因为使用sort
frequency :: Ord a => [a] -> [(Int,a)]
frequency list = map (\l -> (length l, head l)) (group (sort list))
Run Code Online (Sandbox Code Playgroud)
根据要求,这是一个解决方案Control.Arrow:
frequency :: Ord a => [a] -> [(Int,a)]
frequency = map (length &&& head) . group . sort
Run Code Online (Sandbox Code Playgroud)
这与ThePestest的答案功能相同,除了
? f g l -> (f l, g l)
Run Code Online (Sandbox Code Playgroud)
被替换为
-- simplified type signature
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
Run Code Online (Sandbox Code Playgroud)
来自Control.Arrow.如果你想避免导入,
liftA2 (,) :: Applicative f => f a -> f b -> f (a, b)
Run Code Online (Sandbox Code Playgroud)
也适用(使用Applicative实例(->) r)
假设rmdups有类型
rmdups :: Eq a => [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
那么你缺少它的一个参数。
frequency :: Eq a => [a] -> [(Int,a)]
frequency list = [(count y list,y) | y <- rmdups list]
Run Code Online (Sandbox Code Playgroud)
但是您得到的错误将有助于诊断。