我是Haskell的新手(请耐心等待),我正在尝试编写一个使用MongoDB的简单程序。如何使用haskell包中的liftDB函数mongodb
我对包装文档中编写的example没有任何问题。
然后我在文档中找到函数liftDB
,我无法弄清楚它是如何工作的。
这是我的尝试:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Database.MongoDB
import Control.Monad
import Control.Monad.Reader
data MongoConfig = MongoConfig{ mContext :: MongoContext }
saveOnDB doc = do
_ <- liftDB $ insert "myDocs" doc
return()
instance HasMongoContext MongoConfig where
mongoContext config = mContext config
main = do
saveOnDB []
putStrLn "hello everybody"
这给我的错误:
No instance for (MonadReader env0 IO)
arising from a use of `saveOnDB'
Possible fix: add an instance declaration for (MonadReader env0 IO)
In a stmt of a 'do' block: saveOnDB []
In the expression:
do { saveOnDB [];
putStrLn "hello everybody" }
In an equation for `main':
main
= do { saveOnDB [];
putStrLn "hello everybody" }
我was't期待它,因为我从来没有提供MongoContext
工作,但这里的问题:
MongoContext
的数据构造函数未被库所公开,所以我想我不应该直接创建它。- 在我看来,它期望在
MonadReader
实例中找到MongoContext
。
这是函数的类型签名:
saveOnDB :: (HasMongoContext env, MonadIO m, MonadReader env m)
=> [Field] -> m()
我怎样才能使它发挥作用?
看起来你需要,使用T他使用从'connect $ host'hostname“'返回的'Pipe'的'access'函数,像'pipe < - connection $ host”hostname“'; '访问管道主“dbName”(saveOnDB [])'。我从来没有使用MongoDB或这个库,所以我不是100%确定的,但类型似乎排队,我很奇怪尝试将某些东西提交到数据库而没有打开它或告诉它的连接要使用哪个数据库。 – bheklilr 2014-11-03 15:59:57
感谢您的回复。是的,你可以这样做。但它真的是我想要了解的函数'liftDB'。所有关于数据库连接的相关信息都存储在MongoContext中(我没有在示例中构造这些信息,因为我不知道构造函数是如何暴露的)。 – 2014-11-05 23:00:02
确实如此,你不应该自己构造一个'MongoContext',构造函数不会被导出,所以库可以确保所有的上下文都是有效的,就像你不能访问'Data.Map的构造函数一样.Map'或'Data.Sequence.Seq',或'base'中的任意数量的其他类型。 'MonadReader'约束来自'liftDB'函数,它的类型为'(MonadReader env m,HasMongoContext env,MonadIO m)=> Action IO a - > m a'。由于'IO'是'MonadIO'的一个实例,所以这个约束被满足,但是'MonadReader env'约束不是。 – bheklilr 2014-11-05 23:05:05