hashmap withdrawal and poor haskell style

Daan Leijen daan@cs.uu.nl
Wed, 3 Apr 2002 15:51:53 +0200


Hi Michal,

Maybe you should use "accumArray" to get your histogram.

> accumArray     :: Ix a => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b

This functions takes a function to combine elements with the same index "a",
an initial element "b", and the range of indices "(a,a)".  We can now write a
histogram function as follows:

> import Array
>
> type Histogram  = Array Char Int
>
> histogram :: String -> Histogram
> histogram input
>    = accumArray (+) 0 (minBound,maxBound) [(c,1) | c <- input]

(The "minBound" and "maxBound" functions are overloaded from the
"Bounded" class and give the minimal and maximal character).

The histogram can be formatted as (leaving out zero entries):

> format :: Histogram -> String
> format histogram
>   = unlines [formatLine char count | (char,count) <- assocs histogram, count > 0]
>
> formatLine :: Char -> Int -> String
> formatLine char count
>   = [char] ++ " " ++ replicate count '*'

And tested:

> test :: FilePath -> IO ()
> test fname
>   = do{ input <- readFile fname
>          ; putStr (format (histogram input))
>          }

The "accumArray" can supposedly be implemented efficiently.
You can read more about that if you want at:
http://www.research.avayalabs.com/user/wadler/papers/array/array.ps

All the best,
    Daan.


----- Original Message -----
From: "Michal Wallace" <sabren@manifestation.com>
To: "D. Tweed" <tweed@cs.bris.ac.uk>
Cc: <haskell-cafe@haskell.org>
Sent: Wednesday, April 03, 2002 2:40 PM
Subject: Re: hashmap withdrawal and poor haskell style


> On Wed, 3 Apr 2002, D. Tweed wrote:
>
> > >     main = do content <- getContents
> > >               let rpt letter = report content letter
> > >               loop rpt alphabet
>
> > I'm a bit confused how this can have worked... in Haskell `let' is used in
> > the context of a `let ..<1>.. in ..<2>..' where the code ellided in <1>
> > binds some names to values which are then used in the expression <2> (as
> > in `let x=sqrt 2 in exp x') and so the contents of main isn't (unless I'm
> > missing something) syntactically Haskell.
>
> Beats me, but it was the only (or at least the first) way I
> could find to create a function inside a do block...
>
> > Overall the code looks like a reasonable transliteration into Haskell; as
> > you get more competent with Haskell you'll find various higher level
> > functions that replace some of your stuff, e.g., stars can be written as
> > stars x = take x (repeat '*').
>
> Neat! :)
>
>
> > Regarding Assoc, try just `import Assoc' without trying to cut down on
> > which entities are imported; if it works then you've missed some needed
> > elements from your import specification (the bit in ()'s after the module
> > name); if it doesn't then it probably can't find Assoc at all.
>
>
> In the latest version of hugs, if you try "import Assoc", you get:
>
> runhugs: Error occurred
> Reading file "assoc.hs":
> Reading file "/usr/share/hugs/lib/exts/Assoc.hs":
> Reading file "/usr/share/hugs/lib/exts/EdisonPrelude.hs":
> Reading file "/usr/share/hugs/lib/exts/Sequence.hs":
> Reading file "/usr/share/hugs/lib/Monad.hs":
> Reading file "/usr/share/hugs/lib/exts/Sequence.hs":
> Reading file "/usr/share/hugs/lib/exts/ListSeq.hs":
> Reading file "/usr/share/hugs/lib/exts/Assoc.hs":
> Parsing
> ERROR "/usr/share/hugs/lib/exts/Assoc.hs":51 - Haskell 98 does not support multiple parameter
classes
>
>
> At least, *I* get that. :) And the -98 flag is just as bad:
>
>
> [~/work/haskell]: runhugs -98 assoc.hs
> runhugs: Error occurred
> Reading file "assoc.hs":
> Reading file "/usr/share/hugs/lib/exts/Assoc.hs":
> Reading file "/usr/share/hugs/lib/exts/EdisonPrelude.hs":
> Reading file "/usr/share/hugs/lib/exts/Sequence.hs":
> Reading file "/usr/share/hugs/lib/Monad.hs":
> Reading file "/usr/share/hugs/lib/exts/Sequence.hs":
> Reading file "/usr/share/hugs/lib/exts/ListSeq.hs":
> Reading file "/usr/share/hugs/lib/exts/Assoc.hs":
> Reading file "assoc.hs":
> ERROR "assoc.hs" - Entity "foldl1" imported from module "Assoc" already defined in module
"Prelude"
>
> Which is why I restricted what was being imported. :)
>
>
> Anyway, thanks for the response! :)
>
> Cheers,
>
> - Michal   http://www.sabren.net/   sabren@manifestation.com
> ------------------------------------------------------------
> Give your ideas the perfect home: http://www.cornerhost.com/
>  cvs - weblogs - php - linux shell - perl/python/cgi - java
> ------------------------------------------------------------
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>