本文介绍了Scotty使用MongoDB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Haskell比较陌生,这是我第一次使用monad变形金刚。我非常感谢您的帮助。

  runQuery :: Pipe  - >查询 - > ActionM(或者失败[文档])
runQuery管道查询=访问管道主营养(查找查询>> =休息)
$ b $ main = do
pipe< - runIOE $ connect $ host127.0.0.1

scotty 3000 $ do
post/$ do
b< - body
let user :: Either String User = orDecode b

的用户用户左err - >文本。 pack $无法解码用户:++ err ++:\ n++(显示b)
右u - >做
让query :: Query =(select [i_name=:[$ in=:map(unpack。name)(foods u)]]stock_foods)
results< - runQuery管道查询
...

我试图查询 mongodb 数据库在 scotty web框架下,但是我得到一个关于 MonadBaseControl 。我是否真的必须通过 scotty 来创建一个连接数据库的实例,以及如何去做这件事?

 没有用于(MonadBaseControl 
IO(scotty-0.7.2:Web.Scotty.Types.ActionT Text IO))的实例

可能的修正:

添加一个实例声明(MonadBaseControl
IO(scotty-0.7.2:Web.Scotty.Types.ActionT Text IO))


解决方案

足够通用,可以在 MonadBaseControl IO MonadIO



例如,您可以选择 IO monad。在这种情况下,您需要 liftIO。在scotty的动作中运行runQuery

$ p $ import Web.Scotty
import Database.MongoDB
将合格的Data.Text.Lazy导入为T
import Control.Monad.IO.Class

runQuery :: Pipe - >查询 - > IO [文档]
runQuery管道查询=访问管道主管营养(查找查询>> =其余)
$ b $ main = do
pipe< - connect $ host 127.0.0.1
scotty 3000 $ do
get/$ do
res< - liftIO $ runQuery管道(选择[]stock_foods)
text $ T .pack $ show res

After MonadBaseControl 实例用于 Scotty.ActionT ,所以不需要提取任何东西。你可以透明地使用mongoDB表单scotty。只需更改类型签名并删除 liftIO s:

  runQuery :: Pipe - >查询 - > ActionM [文档] 
...
获取/$ do
res< - runQuery管道(选择[]stock_foods)
text $ T.pack $ show res


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))
解决方案

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

这篇关于Scotty使用MongoDB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 00:08