On December 21, 2013 09:23:22 AM Gabriel Gonzalez wrote: > I apologize for the delay. Right now I'm going through a large backlog > of things that I delayed while completing my dissertation.
No problems. Hopefully you won't mind my even longer delay then. I still feel that liftMask is wrong, so I wrote a trace program to see for sure if it is or isn't (it is). http://lpaste.net/104220 > On 11/28/2013 2:06 PM, Tyson Whitehead wrote: > > 1 - each group of IO actions becomes embedded it their own underlying > > IO mask operation inside of Proxy's mask, > > 2 - this underlying IO mask operation stashes the associated IO > > unmask function in the IORef inside of Proxy's mask, and > > 3 - the passed Proxy unmask retrieves this and uses unsafeHoist to > > push it through to all further IO actions. > > > > The thing I'm having problems with is that, if there are any more > > interleaving Request or Respond operations (such as the above yield), > > then subsequent IO operations are going to be running in a different > > IO mask operation with a potentially different unmask operation. I > > would think a correct implementation would have to re-read the IORef > > for each group of IO actions as the associated IO unmask may have changed. > > It does. The internal `unmask` function in the implementation of > `liftMask` re-reads the `IORef` to retrieve the most recent unmasking > function. This means that every time your `examplep` proxy calls > `unmask` it is always getting the latest unmasking function and not just > the first one. That's good as this was my understanding of how it is suppose to work. > To clarify things further, let's assume that you write something like this: > > mask $ \restore -> do > io1 > restore io2 > io3 > yield () > io4 > restore io5 > io6 > > This will generate two internal `mask` calls, one of which brackets > `io1` through `io3` and one of which brackets `io4` through `io6`. The > first call to `restore` will use the unmasking function corresponding to > the first internal `mask` call and the second call to `restore` will use > the unmasking function corresponding to the second internal `mask` call. This example is different from mine in that it doesn't have a yield inside the unmask call. This is required to exhibit the bug as my issue was unSafeHoist [in the unmask code] pushing the unmask IO operation through to all further IO actions [in the unmasked portion of the pipeline including those which will operate under a different mask]. We can see this if we run my original example under the trace program (your example works fine) examplep unmask = trace "Proxy unmask" $ unmask $ trace "yield (output functions as original two IO calls)" $ yield () begin Proxy mask begin StateT mask 0 begin Proxy unmask begin StateT unmask 0 begin yield (output functions as original two IO calls) end StateT unmask 0 end StateT mask 0 begin StateT mask 1 begin StateT unmask 0 end yield (output functions as original two IO calls) end StateT unmask 0 begin StateT unmask 0 end StateT unmask 0 end Proxy unmask end StateT mask 1 end Proxy mask (the trace function is now providing the two liftIO putStrLn calls of the original). >From this we can see that unsafeHoist has pushed the "unmask 0" operation >corresponding to the "mask 0" operation through the inner "trace "..." $ yield >()" proxy resulting in it being used both before and after the yield despite >the fact that after the yield we have transitioned to being inside a "mask 1" >operation. Cheers! -Tyson -- You received this message because you are subscribed to the Google Groups "Haskell Pipes" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected].
