如何在 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?