Как создать экземпляр 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

Другие вопросы по тегам