2017-10-17 75 views
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 

它編譯得很好,但我不知道如何實現peekpoke函數。我認爲這些功能的實現方式與this answer中的相同,但只有當列表中的所有元素具有相同的大小時,此實現纔有效。

什麼是實施peekpoke功能遞歸類型的正確方法,其中元素具有浮動大小?

+3

也許你應該首先定義你期望用作Haskell'MyType a'的對應物的C類型。你的'sizeOf'似乎對我有點樂觀。你的C類型可能需要一個int/enum /任何標籤,這有助於區分三種Haskell構造函數;該標籤的大小應添加到所有尺寸。 – chi

+1

值得注意的是,由於歷史原因,「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

+0

@leftaroundabout即使簽名是現在是歷史。通過'TypeApplications'和'AllowAmbigousTypes',它應該* sizeOf :: Storable a => Int',可以通過'sizeOf @ a'使用。 – HTNW

回答

7

對此,您不能有Storable。這些數據類型需要具有固定大小,就像C struct s。另外請注意,sizeof不應該檢查您給它的價值。它只是type參數的代理/載體,因此您可以編寫例如sizeof (undefined::Int)。也許看看Foreign.Marshal.Array

相關問題