这是我的第一个haskell计划! “wordCount”接受一个单词列表并返回一个元组,每个不区分大小写的单词与其使用计数配对。有关代码可读性或性能的改进建议吗?
import List;
import Char;
uniqueCountIn ns xs = map (\x -> length (filter (==x) xs)) ns
nubl (xs) = nub (map (map toLower) xs) -- to lowercase
wordCount ws = zip ns (uniqueCountIn ns ws)
where ns = nubl ws
答案 0 :(得分:25)
祝贺你的第一个项目!
清洁度:丢失分号。请改用新的分层模块名称(Data.List
,Data.Char
)。添加类型签名。随着你对函数组合越来越熟悉,eta收缩你的函数定义(删除最右边的参数)。 e.g。
nubl :: [String] -> [String]
nubl = nub . map (map toLower)
如果您想要非常严格,请使用显式导入列表:
import Data.List (nub)
import Data.Char (toLower)
对于效果:使用Data.Map
来存储关联,而不是nub
和filter
。请特别注意fromListWith
和toList
。使用这些功能,您可以简化实施并同时提高性能。
答案 1 :(得分:15)
提高可读性的一种方法是尝试习惯标准功能。 Hoogle是将Haskell与世界其他地区区分开来的工具之一;)
import Data.Char (toLower)
import Data.List (sort, group)
import Control.Arrow ((&&&))
wordCount :: String -> [(String, Int)]
wordCount = map (head &&& length) . group . sort . words . map toLower
编辑:说明:所以你认为它是映射链:
(map toLower) :: String -> String
小写整个文本
不敏感性words :: String -> [String]
将一段文字拆分为单词sort :: Ord a => [a] -> [a]
排序group :: Eq a => [a] -> [[a]]
收集列表中的标识元素,例如group
[1,1,2,3,3]
- > [[1,1],[2],[3,3]]
&&& :: (a -> b) -> (a -> c) -> (a -> (b, c))
在同一条数据上应用两个函数,然后返回
结果的元组。例如:(head &&& length) ["word","word","word"]
- > ("word", 3)
(实际&&&
更为一般,但简化说明适用于此示例)编辑:或者实际上,在Hackage上查找“multiset”包。
答案 2 :(得分:6)
向更有经验的开发人员寻求反馈总是好的。不过,您可以使用hlint获取有关小规模问题的反馈。它会告诉你关于分层导入,不必要的括号,替代的高阶函数等等。
关于功能,nub1
。如果你没有按照luqui的建议完全删除参数,我至少会删除等式右边xs
左右的括号。
答案 3 :(得分:2)
添加函数的类型签名确实会有所帮助。