chaskellbindingffistorable

How do I create a Storable instance for a recursive type?


I have the following data type in a Haskell module and I would like to write a Storable instace to use it with C via FFI :

data MyType a =
        TypeDouble Double
      | TypeLst [a] 
      | TypeAdd (MyType a) (MyType a) 

I began by defining the sizeOf function :

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

It compile well, but I don't know how to implement the peek and poke functions. I thought implementing these functions the same way as in this answer but this implementation work only if all the elements in the list have the same size which is not the case here.

What is the correct way to implement peek and poke functions for a recursive type where elements have a floating size ?


Solution

  • You can’t have a Storable for this. These datatypes need to have a fixed size, just like C structs. Also, note that sizeof isn’t supposed to inspect the value you give it. It’s just a proxy/carrier for the type argument, so you can write e.g. sizeof (undefined::Int). Maybe take a look at Foreign.Marshal.Array