
On Dec 14, 2007 9:29 AM, Henning Thielemann
I remember there was a discussion about how to implement full 'wc' in an elegant but maximally lazy form, that is counting bytes, words and lines in one go. Did someone have a nice idea of how to compose the three counters from implementations of each counter? I'm afraid one cannot simply use the "split and count fragments" trick then.
Could you turn the folds into scans and use zip3 and last? I.e., something like this: data Triple a b c = Triple !a !b !c deriving Show countChars :: String -> [Int] countChars = scanl (\n _ -> n+1) 0 countChar :: Char -> String -> [Int] countChar c = scanl (\n c' -> if c == c' then n+1 else n) 0 countLines = countChar '\n' countWords = countChar ' ' last' [x] = x last' (x:xs) = x `seq` last' xs zip3' (x:xs) (y:ys) (z:zs) = Triple x y z : zip3' xs ys zs zip3' _ _ _ = [] wc :: String -> Triple Int Int Int wc xs = last' $ zip3' (countChars xs) (countWords xs) (countLines xs) main = print . wc =<< getContents (or use Data.Strict.Tuple -- but that only has pairs and no zip...) - Benja