
On Fri, 15 Oct 2010 09:07:22 +0100, Duncan Coutts
On Thu, 2010-10-14 at 17:45 +0000, Johannes Waldmann wrote:
Hi. I wonder how to do the following properly.
I have one (large) C type, let's call it T, and I want to sell it as an abstract type in Haskell.
I want to use C functions as if they were of type T -> T (pure function, returns a modified copy of the input) and the question is, how to do the memory allocation for that, in particular, how to avoid IO showing up in the (visible) types on the Haskell side:
I don't want IO because I don't want to declare some artificial order of execution - instead I want lazy evaluation. E.g., I might have some Haskell record with a T component which may or may not be evaluated (accessed) at all.
It is exactly for this purpose that the Haskell FFI library includes unsafePerformIO. This is basically *the* legitimate use case for it, so you don't need to feel bad about it.
I still feel bad about it. Its so easy to turn unsafePerformIO into unsafeCoerce, that I can well happen by mistake. I would like to have an unsafePerformIO that is only unsafe w.r.t. performing effects, not breaking the type-system. Here is a suggestion, it may be not new but I never seen it on unsafePerformIO: unsafePerformIO :: Typeable a => IO a -> a unsafePerformIO = ... same code ... Provided that Typeable instance are all generated by the compiler this has the desired effect of preventing generalization of mutable data. Best regards, -- Nicolas Pouillard http://nicolaspouillard.fr