2010-07-25 15 views
7

在我的应用程序中,我需要序列化包含任意数据类型的向量,在这种情况下是双精度列表。为了序列化矢量,我正在导入Data.Vector.Binary。Data.Vector.Binary重叠二进制[a]实例

当加载在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 

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

我能做些什么来序列化这个结构?

编辑:

我用下面的包版本:

  • 矢量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" 
+1

请问您可以发布您使用的Binary和Vector版本? – 2010-07-25 13:16:12

+0

我同意GHCi似乎假定列表是向量。我查看了vector-binary-instances的源代码,但没有找到它。 – 2010-07-25 17:36:39

+1

这并不明显。 Edward Kmett不久前在http://stackoverflow.com/questions/3213490/how-do-i-write-if-typeclass-a-then-a-is-also-an-instance-of-b中解释了这个问题-by-this-definiti – 2010-07-25 17:44:16

回答

7

好吧,我想我在这里看到问题。矢量二进制实例包定义:

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

这是非常糟糕的。这个定义的意思是“对于任何类型'v a',这是一个有效的二进制实例”。这意味着此实例可用于v a匹配的任何类型。这包括(但不限于)所有列表,所有函子和所有单子。作为示范,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,这显然是错误的。

简答题:现在不要使用vector-binary-instances。这个实例被破坏了,并且给定了如何通过Haskell代码传播实例会导致问题。在解决此问题之前,您应该为矢量编写自己的二进制实例。你应该能够将代码从载体二进制实例复制并限制到一个单态矢量型

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

我相信,这将与任何载体,其Data.Vector.Generic.Vector的实例工作。

您也可以联系矢量二进制实例维护者关于此。

+0

非常感谢你的解释,也是Edward Kmett答案的链接有助于理解为什么会发生。引用他:“在很多方面,'实例'和'类'定义的语法是倒退的。”我会遵循你的建议,对此我很感激。 – uu1101 2010-07-25 18:33:36

+0

不客气,我很高兴这很有帮助。 – 2010-07-25 19:16:14

+0

软件包已更新。我现在分别枚举盒装和拆箱矢量案例(请注意,您不能只使用'Vector a',因为这只是盒装的)。 – 2012-12-27 18:30:01