简体   繁体   English

如何为递归类型创建可存储实例?

[英]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 : 我在Haskell模块中有以下数据类型,我想编写一个可存储的实例,将其与C通过FFI一起使用:

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

I began by defining the sizeOf function : 我首先定义了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

It compile well, but I don't know how to implement the peek and poke functions. 它编译得很好,但我不知道如何实现peekpoke函数。 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 ? 对于元素具有浮动大小的递归类型,实现peekpoke函数的正确方法是什么?

You can't have a Storable for this. 你不可能有这个Storable These datatypes need to have a fixed size, just like C struct s. 这些数据类型需要具有固定大小,就像C struct一样。 Also, note that sizeof isn't supposed to inspect the value you give it. 另请注意, sizeof不应检查您提供的值。 It's just a proxy/carrier for the type argument, so you can write eg sizeof (undefined::Int) . 它只是类型参数的代理/载体,因此您可以编写例如sizeof (undefined::Int) Maybe take a look at Foreign.Marshal.Array 也许看看Foreign.Marshal.Array

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM