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

Posted

技术标签:

【中文标题】如何在 Haskell 中将数据类型转换为 BSON?【英文标题】:How does one transform a data type into BSON in Haskell? 【发布时间】:2018-08-22 00:36:46 【问题描述】:

我一直在尝试了解如何使用 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,但我不知道如何将表达式(Q Exp)更改为文档 实现了 derivedBson,但我遇到了与文档中的示例相同的错误

请注意,我对 Haskell 还很陌生,我花了 2 个小时寻找解决方案,但就是想不通。

谢谢。

【问题讨论】:

如果您的项目在 'a' 中不是参数化的,deriveBson 是否工作?另外,您遇到了什么错误? bson-mapping 的模板 Haskell 宏看起来有点奇怪——有什么理由比 bson-generic 或 Aeson 的转换器更喜欢那个包? @leftaroundabout 我只是尝试使用“本机”Data.Bson 包! @MarcTalbot 我试过了,但没有解决。 TemplateHaskell 的“派生”不起作用 【参考方案1】:

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

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 函数,它返回一个单子值,即如果找到该值,如果没有则失败。例如。如果我们的 monad 是 Maybe,那么如果没有找到它会返回一个 Nothing,否则返回一个 Just x,对于 IO,我们会得到一个运行时错误(这是我们想要避免的)。因此,当调用 toBson ... 时,请确保您在像 Maybe _Either String _ 这样的理智单子中执行它。

测试一下

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

如果您想手动跳过实施 - 您需要向我显示错误,我很乐意帮助您解决问题所在。

【讨论】:

ps:代码未编译 - 我现在没有 ghc 非常感谢,这是一个非常了不起的解释和解决方案!你在这方面考虑了很多。我感谢您的努力☺️

以上是关于如何在 Haskell 中将数据类型转换为 BSON?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用“ord”函数在 Haskell 中将 Char 转换为 Int?

在haskell中将整数列表转换为一个Int(如concat)

在 Haskell 中将字符串转换为整数/浮点数?

如何在 flex 中将字符串数据类型转换为日期数据类型

如何在 Swift 中将 JSON 转换为数据类型?

如何在 JPQL 中将字符串转换为图形数据类型