7

在我的应用程序中,我需要序列化一个包含任意数据类型的向量,在本例中是一个双精度列表。为了序列化我正在导入 Data.Vector.Binary 的向量。

在 GHCi 中加载模块时出现以下错误:

Overlapping instances for Binary [Double]
  arising from a use of `decode' at Statistics.hs:57:33-42
Matching instances:
  instance (Data.Vector.Generic.Base.Vector v a, Binary a) =>
           Binary (v a)
    -- Defined in Data.Vector.Binary
  instance (Binary a) => Binary [a] -- Defined in Data.Binary

列表是 Vector 的实例吗?我查看了文档,但找不到这样的实例。

我该怎么做才能序列化这个结构?

编辑:

我正在使用以下软件包版本:

  • 矢量-0.6.0.2
  • 矢量二进制实例-0.1.2
  • 二进制-0.5.0.2

这里还有一个显示问题的片段,这次是一个字符列表:

import Data.Binary
import Data.Vector.Binary
import qualified Data.ByteString.Lazy as L

main = L.writeFile "/tmp/aaa" $ encode "hello"
4

1 回答 1

7

好的,我想我在这里看到了问题。vector-binary-instances 包定义:

instance (Data.Vector.Generic.Base.Vector v a, Binary a) => Binary (v a)

这是非常糟糕的。这个定义意味着“对于任何类型 'v a',这是一个有效的 Binary 实例”。这意味着此实例可用于任何匹配的类型v a。这包括(但不限于)所有列表、所有函子和所有 monad。作为演示,ghci 报告以下内容:

Prelude Data.Binary Data.Vector.Binary Data.ByteString.Lazy> :t getChar
getChar :: IO Char
Prelude Data.Binary Data.Vector.Binary Data.ByteString.Lazy> encode getChar
<interactive>:1:0:
    No instance for (Data.Vector.Generic.Base.Vector IO Char)
      arising from a use of `encode' at <interactive>:1:0-13
    Possible fix:
      add an instance declaration for
      (Data.Vector.Generic.Base.Vector IO Char)
    In the expression: encode getChar
    In the definition of `it': it = encode getChar

在这里,解释器试图将此实例用于getChar :: IO Char,这显然是错误的。

简短的回答:暂时不要使用向量二进制实例。这个实例被破坏了,并且考虑到实例如何通过 Haskell 代码传播,它会导致问题。在解决此问题之前,您应该为向量编写自己的二进制实例。您应该能够从 vector-binary-instances 复制代码并将其限制为单态向量类型

instance (Binary a) => Binary (Vector a) where

我相信这将适用于作为 Data.Vector.Generic.Vector 实例的任何 Vector。

您可能还想就此联系 vector-binary-instances 维护者。

于 2010-07-25T17:41:38.250 回答