So excuse me if this seems half baked, but am I the only one who
thinks the type signatures of utilities like this..
 allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
..are rather inconvenient?

Wouldn't..
 allocaBytes :: Int -> (Ptr a -> b) -> b
..be more useful?

Why? What could the pure function you're passing to allocaBytes do with the pointer?
When would the storage be freed again? The original allocaBytes frees it after the IO action has finished, but before returing itself. How would that apply to the pure version?



To get around this I defined an operator.. infixl 0 <+ (<+) :: (Ptr a -> b) -> ((Ptr a -> IO b) -> IO b) -> b f <+ alloc = unsafePerformIO $ alloc $ \p -> return $ f p

What can f do with the pointer, outside the IO monad, without using unsafePerformIO itself?
Also, if you're passing alloca or allocaBytes for the alloc parameter, how do you make sure that 'f' has been _completely_ evaluated before alloca deallocates the storage again?


Possible explanations that occur to me are..
1- It's technically impossible.
2- It's unnecessary because FFI users can define their own contraptions like
<+ if they want them, assuming the use of unsafePerformIO in this context
really is safe (and unsafePerformIO is available).
3- It's undesirable because the existing forms are better in some way.
4- It's undesirable because it would break existing code (not true AFAICS).

5- because this use of unsafePerformIO is highly dangerous (I think it will lead to segfaults sooner or later) and should be avoided at all costs.
Also,
6- because a pure function cannot do anything useful with a pointer, IMHO.


Cheers,

Wolfgang

_______________________________________________
FFI mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/ffi

Reply via email to