[Haskell-cafe] Small question about something easy

Thomas Schilling nominolo at googlemail.com
Tue Mar 18 08:59:15 EDT 2008

On 18 mar 2008, at 13.51, Luke Palmer wrote:

> On Tue, Mar 18, 2008 at 12:24 PM, iliali16 <iliali16 at gmail.com> wrote:
>>  Now the problem comes here:
>>  play (p1 :>: p2) state
>>              |play p1 state == (i1,state1) && play p2 state1 ==
>> (i2,state2)
>>  = (i1+++i2,state2)
>>
>>  I know that if I manage to do that function the one above with
>> this sign :>:
>>  do not need to be impelmented since this one will cater for all
>> the cases.
>>  Can you please help me?
>
> You just need a nice simple let or where clause:
>
>   play (p1 :>: p2) state = (i1 +++ i2, state2)
>     where
>     (i1,state1) = play p1 state
>     (i2,state2) = play p2 state1
>
> Or equivalently:
>
>   play (p1 :>: p2) state =
>     let (i1, state1) = play p1 state
>         (i2, state2) = play p2 state1
>     in (i1 +++ i2, state2)
>
> And there's nothing lazily recursive about these, just the information
> usage is a little more complex.  But it could be implemented perfectly
> naturally in scheme, for example.
>
> For further exploration: the pattern here where the state is threaded
> through different computations, is captured by the module
> Control.Monad.State. So if "play" returned an object of a State monad,
> such as:
>
>   play :: Logo -> State TurtleState Image
>
> Then this case could be implemented as:
>
>   play (p1 :>: p2) = do
>     i1 <- play p1
>     i2 <- play p2
>     return (i1 +++ i2)
>
> Pretty, ain't it?  A little too pretty if you ask me.  Let's make it
> uglier and shorter still:
>
>   play (p1 :>: p2) = liftM2 (+++) (play p1) (play p2)

Or use Applicative directly:

play (p1 :>: p2) = (+++) <\$> play p1 <*> play p2

More information about the Haskell-Cafe mailing list