Haskell uniq -c emulator code explanation

This code seems a little dumb to me ... Does anyone want to help me explain this?

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
+3
source share
2 answers

uniq_c contains a counter of the number of lines that appear in the list of lines concatenated with a space for a specific line:

*A> uniq_c ["The","quick","brown","fox","fox"]
["1 The","1 quick","1 brown","2 fox"]

*A> uniq_c $ ["The","quick","brown","fox","fox","fox"] ++ (replicate 100 "fox")
["  1 The","  1 quick","  1 brown","103 fox"]

uniq_c'contains a list of tuples (string,count).

tam finds the largest counter (which will be the last occurrence for any particular row).

nl discards the counts so that the counts are correctly justified.

*A> mapM_ putStrLn $ uniq_c $ ["The","quick","brown","fox","fox","fox"] ++ (replicate 100 "fox")
  1 The
  1 quick
  1 brown
103 fox
+3
source

. 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
+6

All Articles