[Haskell-cafe] Re: Types and hashes of hashes, trouble for a Java-programmer...

Achim Schneider barsoap at web.de
Mon Apr 13 12:25:57 EDT 2009

John Smith <smithsnorth at gmail.com> wrote:

> Hi, a java-programmer running into trouble while trying to learn
> Haskell.
> I try to make a hash containing hashes but can not getting a value
> out of the innermost hash - I keep running into type-trouble where IO
> and Maybe monad is getting mixed?
> My attempt:
> removeMaybeHash x =
>   case x of
>   Just ref -> ref
>   Nothing -> HashTable.new (==) (\key -> key)
> test = do
>   h <- HashTable.new (==) (\key -> key)
>   h1 <- HashTable.new (==) (\key -> key)
>   HashTable.insert h 3 h1
>   HashTable.insert h1 1 1000
>   maybeOuterHash <- HashTable.lookup h 3
>   res <- removeMaybe (removeMaybeHash maybeOuterHash) 1000
>   return res
> Any clues?
Just don't use it, someone deserves to be disemboweled for
implementing it via IO.

Most likely, you don't want to have a hash in specific, but a
key->value mapping in general, and the Haskell libs offer more than
one algorithm to do that, the most basic one being Data.Map, and the
rest having more or less the same interface (e.g. IntMap, or Trie).
There are two possibilities to "nest" two maps: The first being
indexing the map by a tuple of both lookup keys, the second one using
two maps, one inside the other. Personally, I always use Data.Map
unless I identify it as a bottleneck after completing the program.

Using tuples should be straight forward, if you want to nest Maps,
you will want to chain two lookup's together. The most straight-forward
way to do this is using Maybe's monad instance, which looks like this:

instance  Monad Maybe  where
    (Just x) >>= k      = k x
    Nothing  >>= _      = Nothing

It "bypasses" the second argument of >>= in case the first argument is
Nothing. Filling in the types, we get

(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b

. "a" is going to be the inner map, which the second lookup will take
as second parameter, so you can write this:

import Data.Map as M

lookup' :: (Ord k, Ord l) => Map k (Map l v) -> k -> l -> Maybe v
lookup' m k l = M.lookup k m >>= M.lookup l

...Somewhere, I once read that monads can be seen as some fancy way to
do OOP's foo.bar().baz(), but I'm not supposed to tell you that: You
should try your best to forget anything you know about programming if
you come from an imperative language and want to learn haskell :)

(c) this sig last receiving data processing entity. Inspect headers
for copyright history. All rights reserved. Copying, hiring, renting,
performance and/or quoting of this signature prohibited.

More information about the Haskell-Cafe mailing list