二进制类型问题
我正在尝试使用 Haskell Bson 和我想保存和加载它们。保存似乎没有问题,但我在使用 Binary.get
函数时遇到输入错误。
这是我的代码:
{-# LANGUAGE GeneralizedNewtypeDeriving, TypeSynonymInstances, FlexibleInstances #-}
module Database.Axiom where
import Data.Bson (Document, Field)
import Data.Bson.Binary (putDocument, getDocument)
import Data.Binary as B (Binary(..), decodeFile, encodeFile)
import Control.Monad (liftM2)
instance Binary Document where
put = putDocument
get = getDocument
data Collection = Collection {
collectionName :: ByteString,
collectionDocs :: [Document]
}
instance Binary Collection where
put (Collection name docs) = B.put name >> B.put docs
get = liftM2 Collection B.get B.get -- < Here is the type error
导致此错误:
Database/Axiom.hs:24:39:
Overlapping instances for Binary [Field]
arising from a use of `B.get'
Matching instances:
instance Binary a => Binary [a] -- Defined in Data.Binary
instance Binary Document -- Defined at Database/Axiom.hs:13:10-24
In the third argument of `liftM2', namely `B.get'
In the expression: liftM2 Collection B.get B.get
In an equation for `get': get = liftM2 Collection B.get B.get
问题是 Document
只是 [Field]
的同义词。但我需要一个 Binary Document
实例,因为没有函数可以序列化单个 Field
。而且, BSON 确实不导出 Binary Field
的任何实例,因此我完全困惑为什么会首先发生此错误。
我尝试使用严格的类型声明,然后使用自制的 get
方法,但是 get :: [Document]
仅当存在 get 时才能很好地工作: :文档
方法。
那么,也许有人可以帮助我?
I am trying to work with the Haskell Bson and I want to save and load them. The saving seems to be no problem, but I get a typing error with the Binary.get
functions.
Here's my code:
{-# LANGUAGE GeneralizedNewtypeDeriving, TypeSynonymInstances, FlexibleInstances #-}
module Database.Axiom where
import Data.Bson (Document, Field)
import Data.Bson.Binary (putDocument, getDocument)
import Data.Binary as B (Binary(..), decodeFile, encodeFile)
import Control.Monad (liftM2)
instance Binary Document where
put = putDocument
get = getDocument
data Collection = Collection {
collectionName :: ByteString,
collectionDocs :: [Document]
}
instance Binary Collection where
put (Collection name docs) = B.put name >> B.put docs
get = liftM2 Collection B.get B.get -- < Here is the type error
Which leads to this error:
Database/Axiom.hs:24:39:
Overlapping instances for Binary [Field]
arising from a use of `B.get'
Matching instances:
instance Binary a => Binary [a] -- Defined in Data.Binary
instance Binary Document -- Defined at Database/Axiom.hs:13:10-24
In the third argument of `liftM2', namely `B.get'
In the expression: liftM2 Collection B.get B.get
In an equation for `get': get = liftM2 Collection B.get B.get
The problem is that Document
is merely a synonym of [Field]
. But I need an instance for Binary Document
, as there are no functions to serialize a single Field
. And moreover, BSON does not export any instances for Binary Field
, so I am completely confused why this error happens in the first place.
I tried it with strict type declaration and then to use a self made get
method, but a get :: [Document]
only works nicely when there's a get :: Document
method.
So, anyone can help me, perhaps?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
虽然有点主观,但我认为最干净、最可靠的修复方法是为
Document
添加一个newtype
。像这样的东西:应该有效。此外,newtype 包装器已完全优化,因此运行时没有任何开销。
Altough a little subjective, I think the cleanest and most robust way to fix is is to add a
newtype
forDocument
. Something like:should work. In addition,
newtype
wrappers are completely optimized away, so there is no overhead at runtime.不要为
Document
定义实例;只需在get
中调用getDocument
而不是B.get
(我认为不需要使用B.
进行限定)Collection
的 code> 定义。Don't define the instance for
Document
; just callgetDocument
instead ofB.get
(which I see no need for qualifying with theB.
) in yourget
definition forCollection
.