
Ben Rudiak-Gould writes:
I'm not arguing about generality; I simply don't understand how your interface is supposed to be used. E.g.:
do ctx <- start ctx1 <- feed ctx array1 [...]
Note my original definition: type Buffer = (Ptr Word8, Int) data StreamProc ctx a = SP { start :: IO ctx , feed :: ctx -> Buffer -> IO ctx , commit :: ctx -> IO a } So you would use it like this: foo :: StreamProc ctx a -> IO a foo sp = do ctx <- start sp (ptr,n) <- "read buffer" ctx' <- feed sp ctx (ptr,n) ... commit sp ctx'
The important thing is whether, from the caller's perspective, the function is pure. If it's pure, it shouldn't be in the IO monad [...]
My stream processors are not pure.
I think you're hoping to have it both ways, capturing destructive- update semantics and value semantics in a single interface. [...] You must decide whether to enforce single-threading or not.
Uh ... I am genuinely uncertain what single-threading versus multi-threading has to do with my API problem. The API should allow _both_, obviously, and I think it does. What I am trying to find is an _abstract_ API that has the same properties but doesn't depend on a specific data type. Right now I have the stream processor version of 'StateT', but I want the stream processor version of 'MonadState m' instead. Peter