I want to manipulate structs of a certain type from FFI through an interface like that provided with STArray
or STRef
in an ST
monad. I'll have my own specific methods with understandable names for the kind of manipulations that are useful for this struct (like readArray
and writeArray
for arrays).
What is the simplest way to implement this?
The implementation for STArray
(based on https://hackage.haskell.org/package/base-4.7.0.2/docs/src/GHC-Arr.html) looks too convoluted for those who do not know some special GHC techniques used for this.
Can I write something on a more simple, understandable level of Haskell?
Remarks
I'm not asking about how to access a struct through FFI.
I'd rather write getter and setter functions in C, and I want to mirror them in Haskell (to get ST-actions like readArray
and writeArray
).
Some thoughts on easy declaration of this kind of interface (a possible GHC extension?)
If I'm not mistaken, I can declare a foreign function as either an IO-action or pure (if I'm sure it is pure). I understand the latter as simply shortcutting wrapping it in unsafePerformIO
:
foreign import ccall safe "getValue.h getValue" effect :: CInt -> Ptr CChar
foreign import ccall safe "getValue.h getValue" pure :: CInt -> IO (Ptr CChar)
So, the idea arises that an intermediate form between "effect" and "pure" could be possible, to save programmer's work. An "effect" limited to a "limited state":
foreign import ccall safe "getValue.h writeValue" writeValue :: (ValueRef s) -> Value -> ST s () -- modeled after writeSTRef
in addition to the standard two variants for this function in GHC:
foreign import ccall safe "getValue.h writeValue" writeValue :: ValueRef -> Value -> IO ()
foreign import ccall safe "getValue.h writeValue" writeValue :: ValueRef -> Value -> () -- must be really bad!
I only can't get the details about ValueRef
right: if we define this unparameterized type, then how can the compiler use a parameterized one to give an ST-action?..
Probably, this is not available in GHC, but could be useful extension, couldn't it?