如何在Haskell中将数据类型转换为BSON?

时间:2018-03-13 16:44:15

标签: haskell mapping bson template-haskell

我一直在努力了解如何使用Haskell的Data.Bson.Mapping包将数据类型转换为文档,但是,我无法弄明白,docs中的示例没有帮助很多。

我该如何解决这个问题?似乎没有关于这方面的任何问题。我将在下面附上相关代码,以便您能够了解我的来源。

{-# LANGUAGE TemplateHaskell #-}

module Main where
import Database.MongoDB.Connection  (host, connect)
import Database.MongoDB.Query       (access, master, insertMany)
import Data.Data                    (Typeable)
import Data.Bson.Mapping

data Item a = Item { content :: a
                   , checked :: Bool
                   } deriving (Eq, Show, Typeable)

到目前为止我尝试了什么

  • selectFields,但我不知道如何将Expression(Q Exp)更改为Document
  • 实现deriveBson,但我得到了与Docs
  • 中的示例相同的错误

请注意,我仍然是Haskell的新手,我花了2个小时寻找解决方案,但是无法理解。

谢谢。

1 个答案:

答案 0 :(得分:2)

你说的是一个错误,但没有发布错误,所以我无法帮助你 - 但序列化你的数据类型应该相当简单

data Item a = Item { content :: a
                   , checked :: Bool
                   } deriving (Eq, Show, Typeable)

instance (Bson a) => Bson (Item a) where
  toBson (Item cont check) = ["content" := Doc (toBson cont)
                             ,"checked" := Bool check]
  fromBson d = do cont  <- "content" `lookup` d
                  check <- "checked" `lookup` d
                  pure $ Item cont check

toBson必须创建一个Document,它只是[Field]的类型同义词,其中Field只是与标记值相关联的Label。当然,我们必须要求a实施序列化和反序列化,才能使Item成为Bson的实例。

对于反序列化,我选择了lookup函数,该函数返回一个monadic值,即找到的值,如果没有,则返回失败的方法。例如。如果我们的monad是Maybe那么它会返回Nothing如果没有找到而Just x否则,对于IO我们会得到一个运行时错误(我们想要避免的事情)。因此,在致电toBson ...时,请确保您在Maybe _Either String _等理智的monad中执行此操作。

测试
toBson ["no-content":=Int64 1, "checked":= Bool True] :: Maybe (Item Int)
toBson ["content":=Int64 1, "unchecked":= Bool True] :: Either String (Item Int)

如果您想手动跳过实施 - 您需要告诉我错误,我很乐意帮助您解决问题。