Haskell uniq -c仿真器代码说明

问题描述

| 这段代码对我来说似乎有点令人困惑。有人在乎通过解释帮助我吗?
uniq_c l = [ nl (tam l) i s | (s,i) <- uniq_c\' l]

tam = maximum . map snd . uniq_c\'

uniq_c\' [] = []
uniq_c\' (h:t) = let (list,rest) = span (==h) t
                    n = length list + 1
                in (h,n) : uniq_c\' rest

nl tam n line = let l = length $ show n
                    l_tam = length $ show tam
                    n\' = replicate (l_tam-l) \" \"
                in concat n\' ++ show n ++ \" \" ++ line
    

解决方法

        
uniq_c
提供一个字符串出现在一个字符串列表中的次数的计数,该字符串列表中包含一个与特定字符串的空格:
*A> uniq_c [\"The\",\"quick\",\"brown\",\"fox\",\"fox\"]
[\"1 The\",\"1 quick\",\"1 brown\",\"2 fox\"]

*A> uniq_c $ [\"The\",\"fox\"] ++ (replicate 100 \"fox\")
[\"  1 The\",\"  1 quick\",\"  1 brown\",\"103 fox\"]
uniq_c\'
提供
(string,count)
的元组列表。
tam
查找最大的计数(这将是任何特定字符串的最后一次出现)。
nl
将计数缩进,以便使计数正确对正。
*A> mapM_ putStrLn $ uniq_c $ [\"The\",\"fox\"] ++ (replicate 100 \"fox\")
  1 The
  1 quick
  1 brown
103 fox
    ,        该代码不是很好。它不会重用任何现有的Haskell库。 这是另一种选择。
group
功能可完成工作;识别重复出现的情况。
length &&& head
取每个这样的子列表并进行计数和单词。最后,
uniq_c
找到最大宽度,并使用
printf
格式化输出。
import Control.Arrow
import Data.List
import Text.Printf

uniq :: (Eq a) => [a] -> [(Int,a)]
uniq = map (length &&& head) . group

uniq_c :: [String] -> [String]
uniq_c l =
    let us = uniq l
        width = length . show . maximum . map fst $ us
    in  map (uncurry $ printf \"%*d %s\" width) us