[Haskell] more newbie questions regarding do syntax,
mondic context & Data.HashTable
Robert Dockins
robdockins at fastmail.fm
Thu Dec 29 09:36:57 EST 2005
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
More information about the Haskell
mailing list