I have not compiled the program so be ware of errors.
`pipeScore` currently loops when you call `go` and also after the yield in
the section:
if isGameOver b'
then yield (Left "Game over. Bye. See you
next time")
else go b'
from the use of `for cat`
I would suggest only looping with one mechanism.
Something like:
pipeScore = go
where
go b = do
x <- await
case x of
Left s -> yield (Left s)
Right n -> do
case score n b of
Right (a', b') -> do
yield (Right (a',b'))
if isGameOver b'
then do
yield (Left "Game over. Bye. See you next
time")
go b
else go b'
Left msg -> do
yield (Left msg)
go b
The second thing that I noticed was that you are not modifying the the
upstream left value or the right left value.
You should look at the pipes-extras `left` and `right` functions on pipes.
You isolate the game board functionality from handling either the left or
the right left value, and isolate the game over functionality.
-- You ignore lefts so you do not need to right a pipe to handle them.
right (right pipeScore' >-> pipeIsGameOver)
-- You can isolate the board state to a tighter pipe if you want to
separate out
-- functionality
pipeScore' = go
where
go b = do
n <- await
let (a', b') = score n b
yield (a', b')
go b'
pipeIsGameOver = do
where
go = do
ex <- await
case ex of
Right (a, b) -> do
if isGameOver b
then do
yield (Left "Game over. Bye. See you next time")
go
else go
Left msg -> do
yield msg
go
The right and left sections of pipeIsGame Over could be broken apart as
well, however those combinators are not in a library that I know of.
They would be translation of the old bindPull operator from pipes-parse-1.0
http://hackage.haskell.org/package/pipes-parse-1.0.0/docs/Control-Proxy-Parse.html#v:bindPull
If you made those combinators then you could write something like
right (right pipeScore' >-> bindPullRight pipeIsGameOver)
pipeIsGameOver' = do
where
go = do
(a, b) <- await
if isGameOver b
then do
yield (Left "Game over. Bye. See you next time")
go
else go
The MVC library does seem to set up to make some of these types of
operation a little more automatic as well as more type safe. I have not
played around with it much yet though so I would not know how to do a
bindPullRight like behavior with it.
I have not benchmarked `right`, `left`, `bindPull` vs handling everything
with explicit case statements. I do think it is much easier to break a
problem down into subproblems with them though.
Patrick
On Sun, May 11, 2014 at 4:58 AM, Pierre R <[email protected]> wrote:
> In the
>
>
> On Saturday, May 10, 2014 2:01:04 AM UTC+2, Gabriel Gonzalez wrote:
>>
>> 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 local state, I guess a loop might be as good, isn't ?
> numbers :: Monad m => Int -> Producer Int m r
> numbers = go
> where
> go n = do yield n; go $! n + 1
>
> `PipeScore` for instance seems to be better expressed as such:
> pipeScore :: (Monad m) => Board -> Pipe (Either String Int) (Either String
> (Int,Board)) m ()
> pipeScore = go
> where
> go b = do
> for cat $ \x -> case x of
> Left s -> yield (Left s)
> Right n -> do
> case score n b of
> Right (a', b') -> do
> yield (Right (a',b'))
> if isGameOver b'
> then yield (Left "Game over. Bye. See you
> next time")
> else go b'
> Left msg -> do
> yield (Left msg)
> go b
>
> --
> 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].
>
--
Patrick Wheeler
[email protected]
[email protected]
[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].