我正在爲C++類編寫一個Haskell包裝器。我決定將它表示爲一個包含指向C++類實例的指針(Foreign.Ptr)的Haskell數據結構。類似的東西。Haskell在對象刪除時調用函數
在C++:
class MyClass {
public:
double my_method();
// ...
};
extern "C" MyClass* cpp_new_MyClass() {
return new MyClass();
}
extern "C" double cpp_my_method(MyClass *obj) {
return obj->my_method();
}
在Haskell:
Data MyClass = MyClass (Ptr())
foreign import ccall "cpp_new_MyClass" cppNewMyClass :: Ptr()
foreign import ccall "cpp_my_method" cppMyMethod :: Ptr() -> Double
mkMyClass :: MyClass
mkMyClass = MyClass cppNewMyClass
myMethod :: MyClass -> Double
myMethod (MyClass ptr) = cppMyMethod ptr
的問題是,我不知道如何正確地執行MyClass的缺失。在某些時候,Haskell垃圾回收器會刪除MyClass對象,但它不會觸發MyClass *內存在C++中釋放。我如何解決這個問題?
我所知道的ForeignPtr,但它使用IO
單子,因爲我要包裝的數據結構,以準確表現爲正常的Haskell數據結構,這是不令人滿意的,而不需要明確分配/釋放內存或IO
單子。
你的班級副作用是免費的嗎?如果沒有,因爲它在C++中很常見,所以你需要使用'IO' monad,或者_carefully_確保你公開一個純粹的接口。這或者失去了參照透明性,這在Haskell中是一個致命的罪過,因爲它會使程序的行爲幾乎無法預測,尤其是當優化器重寫代碼時。 – chi
@chi是的,這是免費的副作用。 – wrwt