2010-07-25 15 views
7

En mi aplicación necesito serializar un vector que contiene un tipo de datos arbitrario, en este caso es una lista de Dobles. Para serializar el vector, estoy importando Data.Vector.Binary.Data.Vector.Binary se superpone a la instancia binaria [a]

Al cargar el módulo en GHCi surge el siguiente error:

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 

es la Lista de una instancia de Vector? Revisé la documentación pero no pude encontrar dicha instancia.

¿Qué puedo hacer para poder serializar esta estructura?

Editar:

estoy usando las siguientes versiones de paquetes:

  • vectores 0.6.0.2
  • vector de binario instancias-0.1.2
  • binary-0.5.0.2

También aquí hay un fragmento que muestra el problema, esta vez con una lista de caracteres:

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

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

¿Podría publicar las versiones de Binario y Vector que está utilizando? –

+0

Estoy de acuerdo en que GHCi parece estar asumiendo que las listas son vectores. He buscado en el código fuente para vector-binary-instances y no lo encontré. –

+1

No es obvio. Edward Kmett explicó este problema no hace mucho en http://stackoverflow.com/questions/3213490/how-do-i-write-if-typeclass-a-then-a-is-also-an-instance-of-b -por-esto-definiti –

Respuesta

7

Bien, creo que veo el problema aquí. El paquete vector-binary-instances define:

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

que es muy malo. Esta definición significa "para cualquier tipo 'v a', esta es una instancia binaria válida". Eso significa que esta instancia está disponible para cualquier tipo que coincida con v a. Eso incluye (pero no se limita a) todas las listas, todos los funtores y todas las mónadas. Como demostración, ghci informa de lo siguiente:

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 

Aquí el intérprete está intentando utilizar este caso para getChar :: IO Char, que es obviamente erróneo.

Respuesta corta: no use vector-binary-instances por el momento. Esta instancia está quebrada, y dado cómo las instancias se propagan a través del código de Haskell causará problemas. Hasta que esto no se solucione, debes escribir tus propias instancias binarias para vectores. Usted debe ser capaz de copiar el código de vector binario-casos y restringirlo a un tipo de vector monomorfa

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

Creo que esto funciona con cualquier vector que es una instancia de Data.Vector.Generic.Vector.

También puede ponerse en contacto con el mantenedor de vector-binary-instances acerca de esto.

+0

Muchas gracias por la explicación, también el enlace a la respuesta de Edward Kmett ayudó a entender por qué sucede. Citando a él: "En muchos sentidos, la sintaxis para las definiciones de 'instancia' y 'clase' es al revés '.Seguiré tus sugerencias, por lo cual estoy agradecido. – uu1101

+0

De nada; Me alegro de que haya sido útil. –

+0

El paquete ha sido actualizado. Acabo de enumerar los casos de vectores en caja y sin caja por separado ahora (tenga en cuenta que no puede usar simplemente 'Vector a', ya que son solo los encuadrados). –

Cuestiones relacionadas