Sorry for the late response, but I was busy preparing for BayHac.

I really loved Tony's `mvc`-based solution (of course I'm biased). The only thing I wanted to add was the following rule of thumb for how to get local vs global state.

For local state, put the `StateT` layer outside the `Pipe` layer and then immediately run the `StateT` layer before composing it with other pipes:

    numbers :: Monad m => Producer Int m r
    numbers = flip evalStateT 0 $ forever $ do
        n <- get
        lift (yield n)
        put $! n + 1

For global state, put the `StateT` layer below the `Pipe` layer, so that other pipes can share it:

    numbers :: Monad m => Producer Int (StateT Int m) r
    numbers = forever $ do
        n <- lift get
        yield n
        lift $ put $! n + 1

This is actually true for all monad transformers. Layering the transformer outside the `Pipe` layer makes it local and layering it inside the `Pipe` layer makes it global.

On 5/8/14, 12:25 PM, Pierre R wrote:
Thanks Patrick for the annotations and explanations.

Thanks Tony. This is great ! I have merged the code. I still don't understand every bit of it but I will give it a shot tomorrow.

Cheers,




On Thursday, May 8, 2014 5:51:17 AM UTC+2, Tony Day wrote:

    Hi Pierre,

    I coded up your front-end in the spirit of Gabe's mvc library.  I
    know you didn't ask that, of course, but G has asked for examples
    of using the mvc library and your example was perfect for the task.

    
https://github.com/tonyday567/afgame/blob/mvc-example/haskell/src/Afgame/MVC.hs
    
<https://github.com/tonyday567/afgame/blob/mvc-example/haskell/src/Afgame/MVC.hs>

    I liked how it turned out.  Most of the IO in the existing pipes
    became messages that get wrapped as part of an Either String
    (Int,Board).  Not perfect but, with the pipeline getting a bit
    messier.

    Most fun was using quickcheck on the game logic.  I can guess from
    qc that the game lasts for 15 moves, that a high score is around
    200, and that moves of 15 and consecutive moves that add up to 15
    are strong.  Not bad considering I haven't even read the rules!

    On Tuesday, May 6, 2014 5:32:37 AM UTC+10, Pierre R wrote:

        Hi,

        I have added a little pipes frontend to one of my pet example
        and I was wondering how idiomatic (or not) it is.

        http://lpaste.net/103623

        Basically instead of consuming a list with mapM (the `scores`
        function) I am streaming input from stdin. Consequently I need
        to treat the end of game differently than a bogus shot.

        Nothing to do with Pipes but I am not sure annotation 2 is
        better because it forces all client `score` code to unwrap
        StateT whereas I only need the state monad when I have to deal
        with a list of shots. Is there a more idiomatic way to do this ?

        The github repo is here :
        https://github.com/PierreR/afgame/tree/master/haskell
        <https://github.com/PierreR/afgame/tree/master/haskell>

        Thanks for your feedback

--
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] <mailto:[email protected]>. To post to this group, send email to [email protected] <mailto:[email protected]>.

--
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].

Reply via email to