4

我对 Haskell 比较陌生,这是我第一次使用 monad 转换器。我真的很感激一些帮助。

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  
            ...

我正在尝试mongodb在 Web 框架下查询数据库scotty,但我收到关于MonadBaseControl. 我真的必须创建一个实例才能使用 连接到数据库scotty,我将如何去做?

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))
4

1 回答 1

7

mongoDB足够通用,可以在任何作为MonadBaseControl IOand实例的 monad 中工作MonadIO

例如,您可以选择IOmonad。在这种情况下,您需要liftIO . runQuery在 scotty 的操作中:

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

@Sebastian Philipp 添加 MonadBaseControl实例后Scotty.ActionT,无需解除任何内容。您可以透明地使用 mongoDB form scotty。只需更改类型签名并删除liftIOs:

runQuery :: Pipe -> Query -> ActionM [Document]
...
    get "/" $ do
      res <- runQuery pipe (select [] "stock_foods")
      text $ T.pack $ show res
于 2014-10-13T07:58:05.267 回答