在haskell简单的字数

时间:2011-10-18 06:50:20

标签: haskell

这是我的第一个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

4 个答案:

答案 0 :(得分:25)

祝贺你的第一个项目!

清洁度:丢失分号。请改用新的分层模块名称(Data.ListData.Char)。添加类型签名。随着你对函数组合越来越熟悉,eta收缩你的函数定义(删除最右边的参数)。 e.g。

nubl :: [String] -> [String]
nubl = nub . map (map toLower)

如果您想要非常严格,请使用显式导入列表:

import Data.List (nub) 
import Data.Char (toLower)

对于效果:使用Data.Map来存储关联,而不是nubfilter。请特别注意fromListWithtoList。使用这些功能,您可以简化实施并同时提高性能。

答案 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)

添加函数的类型签名确实会有所帮助。