2
votes

So, the idea is that I would take the following code used to run MongoDB queries in haskell

And I would like to turn it into this, so that I can pretend that the run function is a "db", like in the normal mongo driver.

db <- connectDb "127.0.0.1" "testdb" 
db $ delete $ select [] "mycollection"

Here's the function I wrote to do it:

mdb :: (MonadIO m) => String -> String -> IO (Action m a -> m (Either Failure a))
mdb hostname dbname = do
    pipe <- runIOE $ connect $ host hostname
    return (access pipe master (pack dbname))

I got the type by leaving it untyped, then asking ghci what the type was. I barely understand it.

So here's the question

When I make my program have ONLY db <- connectDb "127.0.0.1" "testdb" and don't use it, it fails with this Ambiguous Type error: https://gist.github.com/1337864 - How can I make it unambiguous? Is it a bad idea to make this kind of an abstraction? How would you do it?

1

1 Answers

6
votes

I always feel like answering these questions "this is because your type is ambiguous". For example, if you were given a value:

MonadIO m => (Action m a -> m (Either Failure a))

And told the monad m is a particular monad (not just any one), can you tell which one it is? No.

If you don't use the returned value in a context that makes it apparent to which Monad m belongs, then you need to give the compiler additional information:

db <- connectDB "127.0.0.1" "testdb" :: IO (Action IO a -> IO (Either Failure a))