Sto scrivendo un wrapper Haskell per una classe C++. Ho deciso di rappresentarlo come una struttura dati Haskell contenente un puntatore (Foreign.Ptr) all'istanza della classe in C++. Qualcosa del genere.Chiamare una funzione alla cancellazione dell'oggetto in Haskell
In 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();
}
In 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
Il problema è, non so come implementare correttamente MyClass eliminazione. Ad un certo punto, Garbage Collector Haskell cancellerà l'oggetto MyClass, ma non attiverà la memoria MyClass * liberando in C++. Come lo aggiusto?
Sono consapevole di ForeignPtr, ma utilizza IO
Monade, che non è soddisfacente perché voglio la struttura di dati avvolto a comportarsi esattamente come un normale struttura dati Haskell, senza la necessità di ripartisce esplicito/liberare memoria o IO
monadi .
Il tuo effetto collaterale di classe è gratuito? In caso contrario, come è comune in C++, si deve _ad usare la monade 'IO', o _carefully_ assicurarti di esporre un'interfaccia pura a quella. Questo, o perdere la trasparenza referenziale, che è un peccato mortale in Haskell poiché renderà quasi impossibile prevedere il comportamento del programma, specialmente quando l'ottimizzatore riscrive il tuo codice assumendolo. – chi
@chi Sì, è privo di effetti collaterali. – wrwt