【问题标题】:Scotty Using MongoDBScotty 使用 MongoDB
【发布时间】:2014-06-25 05:41:19
【问题描述】:

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

我正在尝试在scotty Web 框架下查询mongodb 数据库,但我收到关于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))

【问题讨论】:

  • 您应该在您的问题中包含足够的代码(包括所有导入,以及您从 Hackage 中使用的包的名称),以便我们可以尝试自己编译。它使调试和测试不同的解决方案变得更加容易。我猜您可以在您的runQuery 中使用简单的lift 来解决此问题,但无法对其进行测试。
  • 我真的很感激。事实证明我需要lift runQuery 函数并将其返回类型从ActionM (Either ...) 更改为IO (Either ...)。我想我现在可以在 monad 转换器方面取得更多进展!
  • 如果有帮助,我正在经历一些非常相似的事情:将 Scotty 与 Persistent 一起使用,并试图弄清楚如何使用转换器。这里有一些代码似乎可以工作:github.com/stu-smith/Brandy/blob/master/src/Api/Users.hs
  • (忘了说:我可能应该使用liftIO而不是多个lifts...还有很多我要做的整理工作,所以请不要认为代码我发布是明智的:我只是出于兴趣而发布它。
  • github.com/scotty-web/scotty/pull/82 为 ActionT 添加 MonadBaseControl 实例的拉取请求。

标签: mongodb haskell monads monad-transformers scotty


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 2020-03-30
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    相关资源
    最近更新 更多