ForeignPtr
s нельзя сделать Storable
, потому что их реализация требует способа связать один или несколько указателей финализатора с необработанным указателем, и эта связь зависит от времени выполнения.Чтобы сделать ForeignPtr
хранимым, вам нужно сохранить связанный Ptr
(что легко) и массив связанных финализаторов (что невозможно, поскольку финализаторы являются внутренними во время выполнения и могут связываться с GC GHC).время выполнения).
Однако это не та проблема, которую нужно здесь решать.
Проблема в том, что нет разумного способа превратить что-либо, содержащее Vector
, во что-то Storable
.Vector
требует управляемой памяти для своего содержимого (определение Storable.Vector
равно data Vector a = Vector Int (ForeignPtr a)
плюс некоторые аннотации строгости), но вся цель Storable
состоит в сохранении некоторого значения в неуправляемая память.Кроме того, Vector
использует различные объемы памяти в зависимости от ее длины, но Storable
структуры данных должны использовать постоянный объем памяти.
Вам нужнопереосмыслить то, что ваша структура данных пытается моделировать.Вы действительно должны хранить Vector
как это?Помните, что вы храните Vector
из Elems
, что означает, что вы можете иметь значение T
, которое содержит Vector
, которое содержит T
, которое содержит Vector
, которое содержит T
, и т. Д..
Я думаю, что вместо этого вы пытаетесь смоделировать следующую структуру данных, но я могу ошибаться:
data Elems = OneElem Elem | ManyElems (Vector Elem)
data Elem
= I !GHC.Int.Int32
| S !GHC.Int.Int32 !(Ptr CChar)
Если вам действительно нужна рекурсивная структура данных, которую вы описали, попробуйтечтобы реализовать это вместо этого:
data Elems
= I !GHC.Int.Int32
| S !GHC.Int.Int32 !(Ptr CChar)
| T !GHC.Int.Int32 !(Ptr Elems)
Указатель на некоторую Elems
использует постоянную память и может указывать на неуправляемую память, так что вы можете создавать сохраняемые экземплярыза это.