Question: I'm trying to use Data.Map to map strings to functions. The issue I'm having is that the main error handling in my program uses an Either monad, and `Map.lookup` will return `Maybe ([SomeVal] -> Either ValError SomeVal)`. How can I make `Map.lookup` play nicely with the Either monad in this case?

```
apply :: String -> [SomeVal] -> Either ValError SomeVal
apply s args = (Map.lookup s prims) >>= \fn -> fn args

prims :: Map String ([SomeVal] -> Either ValError SomeVal)
prims = Map.fromList
    [("key", function)
    ,("key2", function2)
    ]

::> apply "key" [val1, val2, val3]

```

Answer: 
The [`Control.Error` package](http://hackage.haskell.org/package/errors-1.2.1/docs/Control-Error-Util.html) has a nice function

```
note :: e -> Maybe a -> Either e a
note e Nothing  = Left e
note _ (Just a) = Right a

```

which is useful for "upgrading" `Maybe`-like failures to `Either`-like ones.

```
lookupNote :: k -> Map.Map k v -> Either ValError v
lookupNote k = note (Missing k) . lookup k

```

It also has many others like this for mapping between transformers of `Either` and `Maybe` and generic `MonadPlus` instances. I highly recommend that package.
That depends on how you want to handle the `Nothing` case. If you want to assert that the key will always be there (a bad idea)

```
import Data.Maybe
apply s args = (prims ! s) args

```

But the smarter method is to have a sane value in the case where nothing is found. Likely you'll want some `ValError` constructor

```
ValError = ...
         | NoKey String
         ...
apply s args = maybe (Left $ NoKey s) ($args) $ M.lookup s prims

```

Or want to just keep the `Maybe`

```
apply :: String -> [SomeVal] -> Maybe (Either ValError SomeVal)

```

Either of these methods provide much saner semantics in the case where the key wasn't found. Which you choose is mostly preference, if you intend to make `apply` a pretty fundamental part of your API so much so that `ValError`s should know about it, then 1 works great.

Otherwise, 2 is more painful to use, but doesn't require changing any existing code which is pleasant.