Giorgio Mossa
Giorgio Mossa

Reputation: 245

Strange error using Data.Map in haskell

I'm trying to write a really simple editor like "ed". In this program I'm trying to use a mapping for building the control which translate string-command in actions to perform. Here's a piece of code:

commands :: Map String ([Handle] -> IO ())
commands = fromAscList [
   ("o",\list -> print "Insert name of the file to be opened" >> getLine >>= \nomefile -> 
       openFile nomefile ReadWriteMode >>= \handle -> editor (handle:list)),
   ("i",\list -> case list of { [] -> print "No buffer open" ; handle:res -> write handle } >> editor list),
   ("q",\list -> if list == [] then return () else mapM_ hClose list >> return ())
]

editor :: [Handle] -> IO()
editor list = do
  command <- getLine
  let action = lookup command commands
  case action of
     Nothing  -> print  "Unknown command" >> editor list 
     Just act -> act list

The problem is that when I execute the editor function, either in ghci or in an executable file, when I type "o" I get the message "Unknown command" instead of the call to the function to open the file. I've tryed the same code using associative list instead of Map and in this case it works. So what could be the problem here?

What's more odd is that if I call keys on the mapping commands in ghci it return a list containing the string "o" too.

I thank in advance for any help.

Upvotes: 1

Views: 242

Answers (1)

Daniel Fischer
Daniel Fischer

Reputation: 183968

commands :: Map String ([Handle] -> IO ())
commands = fromAscList [
   ("o",_),
   ("i",_),
   ("q",_)
]

But

ghci> Data.List.sort ["o","i","q"]
["i","o","q"]

You were lying to Data.Map, so it constructed a Map that didn't satisfy the required invariants. Thus looking up things in the Map didn't work, since the request was sent down the wrong branch (sometimes).

Upvotes: 6

Related Questions