Data.Vector.Binary 与 Binary [a] 实例重叠

发布于 2024-09-11 19:50:18 字数 842 浏览 13 评论 0原文

在我的应用程序中,我需要序列化包含任意数据类型的向量,在本例中是双精度列表。为了序列化向量,我导入 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 的实例吗? 我查看了文档但找不到这样的实例。

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

编辑:

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

  • vector-0.6.0.2
  • vector-binary-instances-0.1.2
  • binary-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"

In my application I need to serialize a vector containing an arbitrary datatype, in this case is a list of Doubles. For serializing the vector I'm importing Data.Vector.Binary.

When loading the module in GHCi the following error arises:

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

Is the list an instance of Vector?
I looked through the documentation but could not find such instance.

What can I do to be able to serialize this structure?

Edit:

I'm using the following package versions:

  • vector-0.6.0.2
  • vector-binary-instances-0.1.2
  • binary-0.5.0.2

Also here is a snippet that shows the issue, this time with a list of chars:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

简美 2024-09-18 19:50:18

好吧,我想我看到了问题所在。 vector-binary-instances 包定义:

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

这是非常糟糕的。这个定义意味着“对于任何类型‘v a’,这是一个有效的 Binary 实例”。这意味着此实例可用于与 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

Here the Interpreter is attempts to use this instance for getChar :: IO Char,这显然是错误的。

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

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

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

您可能还需要联系向量二进制实例维护者来了解此事。

Ok, I think I see the problem here. The vector-binary-instances package defines:

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

which is very bad. This definition means "for any type 'v a', this is a valid Binary instance". That means this instance is available for any type that matches v a. That includes (but is not limited to) all lists, all functors, and all monads. As a demonstration, ghci reports the following:

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

Here the interpreter is attempting to use this instance for getChar :: IO Char, which is obviously wrong.

Short answer: don't use vector-binary-instances for now. This instance is broken, and given how instances propagate through Haskell code it will cause problems. Until this is fixed, you should write your own binary instances for vectors. You should be able to copy the code from vector-binary-instances and restrict it to a monomorphic vector type

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

I believe this will work with any Vector which is an instance of Data.Vector.Generic.Vector.

You also may want to contact the vector-binary-instances maintainer about this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文