2010-07-25 4 views
7

In meiner Anwendung muss ich einen Vektor mit einem beliebigen Datentyp serialisieren, in diesem Fall ist eine Liste von Doubles. Zum Serialisieren des Vektors importiere ich Data.Vector.Binary.Data.Vector.Binary überlappt Binary [a] Instanz

Beim Laden des Moduls in GHCi der folgenden Fehler auftritt:

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 

Ist die Liste eine Instanz von Vector? Ich habe die Dokumentation durchgesehen, konnte aber keine solche Instanz finden.

Was kann ich tun, um diese Struktur zu serialisieren?

Edit:

ich die folgenden Paketversionen bin mit:

  • Vektor-0.6.0.2
  • Vektor-binary-Instanzen-0.1.2
  • binär 0.5.0.2

auch hier ist ein Ausschnitt, der das Problem zeigt, diesmal mit einer Liste von Zeichen:

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

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

Könnten Sie bitte die Versionen von Binary und Vector, die Sie verwenden, posten? –

+0

Ich stimme zu, dass GHCi davon ausgeht, dass Listen Vektoren sind. Ich habe den Quellcode für Vektor-Binär-Instanzen durchgesehen und nicht gefunden. –

+1

Es ist nicht offensichtlich. Edward Kmett erklärte dieses Problem vor nicht langer Zeit in http://stackoverflow.com/questions/3213490/how-do-i-write-if-typeclass-a-thena-a-iso-in-instance-of-b -by-this-definiti –

Antwort

7

Ok, ich denke, ich sehe das Problem hier. Das Paket vector-binary-instances definiert:

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

was sehr schlecht ist. Diese Definition bedeutet "für jeden Typ 'v a', dies ist eine gültige Binäre Instanz". Das bedeutet, dass diese Instanz für jeden Typ verfügbar ist, der v a entspricht. Dies beinhaltet (ist aber nicht beschränkt auf) alle Listen, alle Funktoren und alle Monaden. Als Demonstration, berichtet GHCI die folgende:

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 

Hier ist der Interpreter versucht, diese Instanz zu verwenden, für getChar :: IO Char, was offensichtlich falsch ist.

Kurze Antwort: Verwenden Sie keine Vektor-Binär-Instanzen für jetzt. Diese Instanz ist defekt, und wenn Instanzen durch Haskell-Code weitergeleitet werden, führt dies zu Problemen. Bis dies behoben ist, sollten Sie Ihre eigenen binären Instanzen für Vektoren schreiben. Sie sollten den Code aus Vektor-binary-Instanzen und es

auf einen monomorphic Vektortyp beschränken kopieren können,
instance (Binary a) => Binary (Vector a) where 

Ich glaube, das mit jedem Vektor arbeiten, die eine Instanz von Data.Vector.Generic.Vector ist.

Sie können auch den Vector-Binary-Instances Maintainer kontaktieren.

+0

Vielen Dank für die Erklärung, auch der Link zu Edward Kmetts Antwort hat geholfen zu verstehen, warum es passiert. Zitier ihn: "In vielerlei Hinsicht ist die Syntax für" Instanz "- und" Klassen "-Definitionen rückwärts.Ich werde deinen Vorschlägen folgen, wofür ich dankbar bin. – uu1101

+0

Gern geschehen; Ich bin froh, dass es hilfreich war. –

+0

Das Paket wurde aktualisiert. Ich zähle die Kästen mit und ohne Kästchen jetzt getrennt auf (beachte, dass du 'Vektor a' nicht benutzen kannst, da das nur die Kästchen sind). –