Data.Vector.Binary overrides binary instance [a]

In my application, I need to serialize a vector containing an arbitrary data type, in this case it is a list of doubles. To serialize a vector, I import Data.Vector.Binary.

When loading a module into GHCi, the following error occurs:

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 va, Binary a) => Binary (va) -- 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 an instance.

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

Edit:

I use the following package versions:

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

Also shown is a snippet that shows the problem, this time with a list of characters:

 import Data.Binary import Data.Vector.Binary import qualified Data.ByteString.Lazy as L main = L.writeFile "/tmp/aaa" $ encode "hello" 
+7
vector serialization haskell instances overlapping
source share
1 answer

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

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

which is very bad. This definition means "for any type of" va ", it is a valid binary instance." This means that this instance is available for any type that matches va . This 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 trying to use this instance for getChar :: IO Char , which is obviously not true.

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

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

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

You can also refer to the constructor of vector-binary instances about this.

+7
source share

All Articles