Подтвердить что ты не робот

Как написать экземпляр Data.Vector.Unboxed в Haskell?

У меня есть числовое приложение, которое выполняет большую работу с отрицательными логами вероятностей, которые (поскольку вероятности варьируются от нуля до единицы) принимают значения положительных удвоений или отрицательную бесконечность (если базовая вероятность равна нулю).

Я использую их с newtype Score следующим образом:

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

Теперь, в реализации алгоритма Витерби, я много использовал Data.Vector, и действительно, у меня есть Data.Vector Score s. При попытке выполнить некоторую настройку производительности я решил попробовать использовать Data.Vector.Unboxed. Однако мне нужно написать экземпляр для Unbox, который не может быть получен, и я не могу понять, что мне нужно сделать (в частности, что такое контракт для Unbox typeclass). Поскольку Score действительно является Double с некоторыми полезными конструкторами и семантикой, это должно быть возможно, я думаю. Насколько я могу судить, мне нужно сказать Data.Vector.Unboxed, насколько большой должен быть каждый слот в векторе Score, и я думаю, как читать и писать (но, черт возьми, они очень похожи Double с).

Итак, что мне делать? Спасибо!

4b9b3361

Ответ 1

Класс типа Unbox не имеет методов - он просто сокращает классы классов Vector и MVector. Выведите те, а класс Unbox поступит бесплатно (либо путем получения, либо путем простого написания instance U.Unbox Score на собственной строке).

{-# 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)