2
我已经一个Haskell模块中的以下数据类型和我想写可储存instace经由FFI与C使用它:如何为递归类型创建一个Storable实例?
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
函数。我认为这些功能的实现方式与this answer中的相同,但只有当列表中的所有元素具有相同的大小时,此实现才有效。
什么是实施peek
和poke
功能递归类型的正确方法,其中元素具有浮动大小?
也许你应该首先定义你期望用作Haskell'MyType a'的对应物的C类型。你的'sizeOf'似乎对我有点乐观。你的C类型可能需要一个int/enum /任何标签,这有助于区分三种Haskell构造函数;该标签的大小应添加到所有尺寸。 – chi
值得注意的是,由于历史原因,“sizeOf”具有错误的签名。它实际上应该是['Tagged a Int'](http://hackage.haskell.org/package/tagged-0.8.5/docs/Data-Tagged.html#t:Tagged)(或'proxy a - > Int ')而不是'a - > Int'。这将清楚地表明,这实际上不能取决于各个值_,但对于给定类型的_all_值应该是相同的。 ([文档](http://hackage.haskell.org/package/base-4.10.0.0/docs/Foreign-Storable.html#v:sizeOf)确实会这么说)。 – leftaroundabout
@leftaroundabout即使签名是现在是历史。通过'TypeApplications'和'AllowAmbigousTypes',它应该* sizeOf :: Storable a => Int',可以通过'sizeOf @ a'使用。 – HTNW