Scotty Using MongoDB

心不动则不痛 提交于 2019-12-07 09:56:35

问题


I'm relatively new to Haskell, and this is my first time working with monad transformers. I'd really appreciate some help.

runQuery :: Pipe -> Query -> ActionM (Either Failure [Document])
runQuery pipe query = access pipe master "nutrition" (find query >>= rest) 

main = do
pipe <- runIOE $ connect $ host "127.0.0.1"  

scotty 3000 $ do
post "/" $ do
        b <-  body
        let user :: Either String User = eitherDecode b
        case user of 
            Left err -> text . pack $ "Could not decode the user:" ++ err ++ ":\n" ++ (show b)
            Right u -> do 
            let query::Query = (select ["i_name" =: ["$in" =: map (unpack . name) (foods u)]] "stock_foods")
            results <- runQuery pipe query  
            ...

I'm trying to query a mongodb database under the scotty web framework, but I'm getting an error about MonadBaseControl. Do I really have to make an instance of this to connect to a database with scotty, and how would I go about doing it?

No instance for (MonadBaseControl
                   IO (scotty-0.7.2:Web.Scotty.Types.ActionT Text IO))
  arising from a use of `find'
Possible fix:
  add an instance declaration for
  (MonadBaseControl
     IO (scotty-0.7.2:Web.Scotty.Types.ActionT Text IO))

回答1:


mongoDB is generic enough to work in any monad that is instance of MonadBaseControl IO and MonadIO.

For example, you can choose IO monad. In this case you need liftIO . runQuery inside scotty's action:

import Web.Scotty
import Database.MongoDB
import qualified Data.Text.Lazy as T
import Control.Monad.IO.Class

runQuery :: Pipe -> Query -> IO [Document]
runQuery pipe query = access pipe master "nutrition" (find query >>= rest) 

main = do
  pipe <- connect $ host "127.0.0.1"
  scotty 3000 $ do
    get "/" $ do
      res <- liftIO $ runQuery pipe (select [] "stock_foods")
      text $ T.pack $ show res

After @Sebastian Philipp added MonadBaseControl instance for Scotty.ActionT, there is no need to lift anything. You can transparently work with mongoDB form scotty. Just change type signature and drop liftIOs:

runQuery :: Pipe -> Query -> ActionM [Document]
...
    get "/" $ do
      res <- runQuery pipe (select [] "stock_foods")
      text $ T.pack $ show res


来源:https://stackoverflow.com/questions/23531465/scotty-using-mongodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!