"he uses the IO monad, which does not satisfy, because I want the packed data structure to behave exactly like a normal Haskell data structure"
Of course, yes, but, unfortunately, this is really impossible. Foreign "functions" can always do funny things that may not be possible in Haskell; the type system is not able to look there and prevent it.
This dilemma is the only (!) Reason we have unsafePerformIO , and really yours, is a good example of a valid application for this thing.
I haven't done it myself yet, but your code should look something like this:
extern "C" void cpp_delete_MyClass(MyClass* obj) { delete obj; }
foreign import ccall "cpp_new_MyClass" cppNewMyClass :: IO (Ptr ()) foreign import ccall "&cpp_delete_MyClass" cppDeleteMyClass :: FunPtr (Ptr () -> IO ()) data MyClass = MyClass (ForeignPtr ()) mkMyClass :: MyClass mkMyClass = unsafePerformIO $ do newObj <- cppNewMyClass fPtr <- newForeignPtr cppDeleteMyClass newObj return $ MyClass fptr
I'm not quite sure about these FunPtr s, I hope someone comments on this ...
leftaroundabout
source share