Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine two monads when neither has a transformer?

I'm playing around with writing a web app. In this case, I'm using scotty and redis, but this problem comes up in any web/db combo. I used happstack before this, so I'd love an example there too.

Scotty has you define routes in a nested monad, which makes it easy to access the database connection within a route:

main = do
    db <- connect defaultConnectInfo
    scotty 3000 $ do

    get "/keys" $ do
        keys <- liftIO $ runRedis db $ keys "*"
        html $ T.pack $ show keys

The do block in get has type: Web.Scotty.ActionM (). All the redis commands have type Database.Redis.Redis a. Neither redis or scotty has a monad transformer.

What's the best way to combine these? I'm new to haskell, but I did manage to get ReaderT working with the web monad in happstack.

Ideally, I could somehow make a new monad stack that supports both keys and html in the same do block.

like image 919
Sean Clark Hess Avatar asked Jan 27 '12 13:01

Sean Clark Hess


1 Answers

For some reason I felt like liftIO was ugly, but it's really not bad. Especially if you do this:

queryRedis :: Connection -> Redis a -> ActionM a
queryRedis db r = liftIO $ runRedis db r

And define a partially applied function redis = queryRedis db. Thanks everyone

like image 190
Sean Clark Hess Avatar answered Oct 19 '22 21:10

Sean Clark Hess