В моем приложении я должен сериализировать вектор, содержащий произвольный тип данных, в этом случае список, Удваивается. Для сериализации вектора я импортирую Данные. Вектор. Двоичный файл.
При загрузке модуля в GHCi возникает следующая ошибка:
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
Действительно ли список является экземпляром Вектора? Я просмотрел документацию, но не мог найти такой экземпляр.
Что я могу сделать, чтобы смочь сериализировать эту структуру?
Править:
Я использую следующие версии пакета:
Также вот отрывок, который показывает проблему, на этот раз со списком символов:
import Data.Binary
import Data.Vector.Binary
import qualified Data.ByteString.Lazy as L
main = L.writeFile "/tmp/aaa" $ encode "hello"
Так, кажется, я вижу проблему. Пакет vector-binary-instances определяет:
instance (Data.Vector.Generic.Base.Vector v a, Binary a) => Binary (v a)
что очень плохо. Это определение означает "для любого типа 'v a' это допустимый экземпляр Binary". Это означает, что данный экземпляр доступен для любого типа, который соответствует v a
. Это включает (но не ограничивается) все списки, все функторы и все монады. В качестве демонстрации ghci сообщает следующее:
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
Здесь интерпретатор пытается использовать этот экземпляр для getChar :: IO Char
, что, очевидно, неправильно.
Короткий ответ: пока что не используйте векторно-бинарные экземпляры. Этот экземпляр сломан, и, учитывая то, как экземпляры распространяются в коде Haskell, это вызовет проблемы. Пока это не исправлено, вы должны написать свои собственные двоичные экземпляры для векторов. Вы должны иметь возможность скопировать код из vector-binary-instances и ограничить его мономорфным типом вектора
instance (Binary a) => Binary (Vector a) where
Я полагаю, что это будет работать с любым Vector, который является экземпляром Data.Vector.Generic.Vector.
Вы также можете связаться с сопровождающим vector-binary-instances по этому поводу.