Скотти, используя MongoDB

Я относительно новичок в Haskell, и я впервые работаю с монадными трансформаторами. Я бы очень признателен за помощь.

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 база данных под 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))

1 ответ

mongoDB достаточно универсален для работы в любой монаде, которая является экземпляром MonadBaseControl IO а также MonadIO,

Например, вы можете выбрать IO монада. В этом случае вам нужно 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 Wagner добавил MonadBaseControl экземпляр для Scotty.ActionTНет необходимости поднимать что-либо. Вы можете прозрачно работать с mongoDB формой Скотти. Просто измените тип подписи и бросьте liftIOs:

runQuery :: Pipe -> Query -> ActionM [Document]
...
    get "/" $ do
      res <- runQuery pipe (select [] "stock_foods")
      text $ T.pack $ show res
Другие вопросы по тегам