On Dec 29, 2005, at 9:06 AM, Hunter Kelly wrote:

Hi there, I'm having some trouble trying to get information out
of a HashTable.

I'm using it to represent a set (I'm using a hash table for O(1)
speed reasons to compare against Data.Sets O(lgN) operations).

I'm trying to write a simple function, member, which returns whether
or not a key is in the HashTable.

I've tried the following:

member :: HashTable String Int -> String -> Bool
member hash x = let r = do return (Data.HashTable.lookup hash x )
                          in case r of
                               Nothing -> False
                               (Just v) -> True

But this seems to always return True.  I _think_ the type of r here is
IO (Maybe Int), but I'm trying to unwrap the IO part.

This is due to the fact that "Maybe" is a monad; r actually has the type "Maybe (IO (Maybe Int))". Calling "return" in the Maybe monad will always generate a value of the form "Just x". Then you pattern match on that and, surprise, it matches "Just v"

However, if I try:

member :: HashTable String Int -> String -> Bool
member hash x = let r = do Data.HashTable.lookup hash x
                           in case r of
                               Nothing -> False
                               (Just v) -> True

I get the following error:


figt.hs:46:31:
    Couldn't match `IO (Maybe Int)' against `Maybe a'
      Expected type: IO (Maybe Int)
      Inferred type: Maybe a
    When checking the pattern: Nothing
    In a case alternative: Nothing -> False



How can I get at the underlying value?  Can I only access it from
within a "do" construct?
Is there anyway to get at this function to return just True or False?

Not really. If it did, then it wouldn't really be a function (in the maths sense).

Or has using something that uses an IO monad "polluted" everything
else that depends on the answer?

Essentially, that is correct. Once you go into the IO monad you can't get back out. You can only use HashTable in IO level code. If you need pure sets, use Data.Set and friends.

This is more or less how I would write the member operation on Data.HashTable.

member:: String -> HashTable String Int -> IO Bool
member x hash = do
      r <- lookup hash x
      return (isJust r)



See the following for more about the IO monad:


http://haskell.org/hawiki/ThatAnnoyingIoType
http://haskell.org/hawiki/UsingIo


Or check out the tutorials at:

http://www.haskell.org/learning.html



Rob Dockins

Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
          -- TMBG

_______________________________________________
Haskell mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell

Reply via email to