2012-06-02 8 views
17

Tengo una aplicación numérica que hace mucho trabajo con registros de probabilidades negativos, que (dado que las probabilidades oscilan entre cero y uno) toman los valores de dobles positivos, o infinito negativo (si la probabilidad subyacente fue cero).¿Cómo escribo una instancia de Data.Vector.Unboxed en Haskell?

estoy usando estas con un newtype Score de la siguiente manera:

newtype Score = Score Double 
    deriving (Eq, Ord) 
--^A "score" is the negated logarithm of a probability 

negLogZero :: Score --^Stands in for - log 0 
negLogZero = Score 10e1024 

negLogOne :: Score --^- log 1 
negLogOne = Score 0.0 

unScore :: Score -> Double 
unScore (Score x) = x 

instance Show Score where 
    show (Score x) = show x 

Ahora, en una implementación del algoritmo de Viterbi, He estado usando Data.Vector mucho, y de hecho tengo algunos Data.Vector s de Score s. Mientras trataba de hacer algunos ajustes de rendimiento, decidí intentar usar Data.Vector.Unboxed. Sin embargo, necesito escribir una instancia para Unbox, que no se puede derivar, y no puedo entender qué debo hacer (particularmente, cuál es el contrato para la clase de tipo Unbox). Dado que Score es realmente un Double con algunos constructores y semántica útiles, esto debería ser posible, creo. Por lo que puedo decir, necesito poder decir Data.Vector.Unboxed qué tan grande debe ser cada ranura en un vector de Score s, y supongo que cómo leerlas y escribirlas (pero diablos, se parecen mucho a Double s) .

Entonces, ¿qué debo hacer? ¡Gracias!

Respuesta

15

La clase de tipo Unbox no tiene ningún método; es solo una abreviatura de las clases de tipo Vector y MVector. Derive esos, y la clase Unbox es gratuita (ya sea por derivación o simplemente escribiendo instance U.Unbox Score en su propia línea).

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 
import Data.Vector.Generic.Base 
import Data.Vector.Generic.Mutable 
import qualified Data.Vector.Unboxed as U 
newtype Score = Score Double deriving (Vector U.Vector, MVector U.MVector, U.Unbox) 
+0

Impresionante, gracias! –

+2

Esto ya no funciona en ghc 7.8.4, dando 'No se pudo forzar desde 'Data.Vector.Primitive.Vector Double' a 'U.Vector Score' porque 'Data.Vector.Primitive.Vector Double' y 'U.Vector La puntuación 'son diferentes tipos. que surge de la coacción del método 'Data.Vector.Generic.Base.basicLength' del tipo 'U.Vector Double -> Int' para escribir 'U.Vector Score -> Int' Solución posible: usar una 'instancia derivada' independiente declaración, por lo que puede especificar el contexto de la instancia usted mismo Al derivar la instancia para (Vector U.Vector Score) ' – unhammer

+1

https://ghc.haskell.org/trac/ghc/ticket/9112 parece relevante, aunque no veo que mencionan una solución. – unhammer

Cuestiones relacionadas