Как создать экземпляр Storable для рекурсивного типа?
У меня есть следующий тип данных в модуле Haskell, и я хотел бы написать Storable instace, чтобы использовать его с C через FFI:
data MyType a =
TypeDouble Double
| TypeLst [a]
| TypeAdd (MyType a) (MyType a)
Я начал с определения sizeOf
функция:
instance Storable a => Storable (MyType a) where
sizeOf (TypeDouble _) = sizeOf (0 :: Double)
sizeOf (TypeLst lst) = sum $ map sizeOf lst
sizeOf (TypeAdd a b) = sizeOf a + sizeOf b
Компилируется хорошо, но я не знаю, как реализовать peek
а также poke
функции. Я думал, что реализовать эти функции так же, как в этом ответе, но эта реализация работает, только если все элементы в списке имеют одинаковый размер, что здесь не так.
Как правильно реализовать peek
а также poke
функции для рекурсивного типа, где элементы имеют плавающий размер?
1 ответ
Вы не можете иметь Storable
за это. Эти типы данных должны иметь фиксированный размер, как C struct
s. Также обратите внимание, что sizeof
не должен проверять ценность, которую вы ему даете. Это просто прокси / носитель для аргумента типа, так что вы можете написать, например, sizeof (undefined::Int)
, Может быть, взглянуть на Foreign.Marshal.Array