我一直在努力了解如何使用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)
到目前为止我尝试了什么
请注意,我仍然是Haskell的新手,我花了2个小时寻找解决方案,但是无法理解。
谢谢。
答案 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)
如果您想手动跳过实施 - 您需要告诉我错误,我很乐意帮助您解决问题。