如何在导管管道中转换单子?

How to transform monads in a conduit pipeline?

我正在尝试使用 Database.MongoDB 包将文件从磁盘复制到 MongoDB GridFS 中的文件。

main :: IO ()
main = do
  pipe <- MDB.connect (host "127.0.0.1")
  _ <- access pipe master "baseball" run
  close pipe

run :: MDB.Action IO GFS.File
run = do
  uploadImage "sandbox/bat.jpg"

uploadImage :: Text -> MDB.Action IO GFS.File
uploadImage src = do
  bucket <- GFS.openDefaultBucket
  runConduitRes $ sourceFileBS (unpack src) .| (hole $ GFS.sinkFile  bucket src)

这不起作用,因为 sourceFileBS 期望作为基础 monad 中的 Resource 而 GFS.sinkFile 想要一个 MongoDB 一个 Action(一个专门的 Reader)。

将这些管道连接在一起的优雅方式是什么?

如果没有所有可用的类型和函数,很难告诉您最好的方法。但是,一种可行的方法如下所示:

withBinaryFile (unpack src) ReadMode $ \h -> runMongo $ runConduit $
  sourceHandle h .| GFS.sinkFile bucket src