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 ?
MyType a
. YoursizeOf
seems to be a bit optimistic to me. Your C type will probably need an int/enum/whatever tag that helps you discriminate between the three Haskell constructors; the size of that tag should be added to all the sizes. – chisizeOf
has, for historical reasons, the wrong signature. It should actually beTagged a Int
(orproxy a -> Int
) rather thana -> Int
. That would make it clear that this can't actually depend on individual values, but should be the same for all value of a given type. (The documentation does say this, though.) – leftaroundaboutTypeApplications
andAllowAmbigousTypes
it should really besizeOf :: Storable a => Int
, usable viasizeOf @a
. – HTNW