Michal,

As Daan Leijen has suggested, `accumArray` is probably the best solution to your simple
histogramming problem.  However, you might also be interested to learn about "finite 
maps", which
are often the appropriate functional analogue to "hash maps".  Finite maps are 
typically
implemented with balanced trees and exhibit O(log n) time cost for insertion and 
lookup.  (The
extra cost over imperative languages' O(1) cost is the price paid for persistence.)  
The following
version of your program runs on Hugs 98 and GHC.  (For GHC you must specify "-package 
data" to
access the `FiniteMap` module.)

> import Char (isAlpha, toLower)
> import FiniteMap

> main :: IO ()
> main = interact (report . histogram)

> type Histo = FiniteMap Char Int

> histogram :: String -> Histo
> histogram = foldl tally emptyFM

> tally :: Histo -> Char -> Histo
> tally histo ch = if isAlpha ch then addToFM_C (+) histo (toLower ch) 1
>                                else histo

> report :: Histo -> String
> report histo = unlines [ line ch | ch <- ['a'..'z'] ]
>  where line ch = ch : " " ++ replicate (count ch) '*'
>        count ch = lookupWithDefaultFM histo 0 ch

Dean Herington

_______________________________________________
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to