[Haskell-cafe] Software Tools in Haskell
Benja Fallenstein
benja.fallenstein at gmail.com
Fri Dec 14 22:39:09 EST 2007
On Dec 14, 2007 9:29 AM, Henning Thielemann
<lemming at henning-thielemann.de> wrote:
> 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
More information about the Haskell-Cafe
mailing list