Buttons and Clicks - State Monad

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Buttons and Clicks - State Monad

GŸuenther Schmidt
Hi,

in this piece here http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=1083#a1083
I'm trying to create a button that, every time when clicked, increases
a counter by one and does a putStrLn of the counters current value.

I'm trying to write this without any use of IORef but merely using the
state monad.

Can anybody show me how to do this?

Günther

The UI Code is wxHaskell
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Buttons and Clicks - State Monad

Cale Gibbard
You might be misunderstanding the purpose of the State Int monad somewhat.

A computation of type State Int a is internally represented by a
function of type Int -> (Int, a). When you call runState, you
effectively apply this pure function to an initial state, and get a
final state and result. You won't be able to do anything with the
State monad that you couldn't already do with such a function, it's
more or less a notational convenience.

In particular, the state of your counter will not be preserved between
calls to runState unless you arrange that the final state returned
from the last call to runState is passed along as the initial state in
the next one. Of course, this effectively defeats the purpose of using
the State monad in the first place.

Since event handlers in wxHaskell must be in the IO monad, there's no
machinery in place to handle forwarding your state along, so the State
monad is not terribly useful here. On the other hand, it's rather easy
to write a function of type State s a -> IORef s -> IO a which takes
the initial state from the IORef and updates the IORef with the new
state.

 - Cale

2009/1/31 guenni68 <[hidden email]>:

> Hi,
>
> in this piece here http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=1083#a1083
> I'm trying to create a button that, every time when clicked, increases
> a counter by one and does a putStrLn of the counters current value.
>
> I'm trying to write this without any use of IORef but merely using the
> state monad.
>
> Can anybody show me how to do this?
>
> Günther
>
> The UI Code is wxHaskell
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Buttons and Clicks - State Monad

GŸuenther Schmidt
Hi Cale,

thanks for the explanation. From my futile attempts I *almost* gathered as  
much.

I guess I was getting confused with documentation saying things like

MonadState
put replaces the state inside the monad.

that this would refer to some sort of update-in-place.

So bottom-line then there is no other way than using IORef.


Günther

Am 31.01.2009, 19:38 Uhr, schrieb Cale Gibbard <[hidden email]>:

> You might be misunderstanding the purpose of the State Int monad  
> somewhat.
>
> A computation of type State Int a is internally represented by a
> function of type Int -> (Int, a). When you call runState, you
> effectively apply this pure function to an initial state, and get a
> final state and result. You won't be able to do anything with the
> State monad that you couldn't already do with such a function, it's
> more or less a notational convenience.
>
> In particular, the state of your counter will not be preserved between
> calls to runState unless you arrange that the final state returned
> from the last call to runState is passed along as the initial state in
> the next one. Of course, this effectively defeats the purpose of using
> the State monad in the first place.
>
> Since event handlers in wxHaskell must be in the IO monad, there's no
> machinery in place to handle forwarding your state along, so the State
> monad is not terribly useful here. On the other hand, it's rather easy
> to write a function of type State s a -> IORef s -> IO a which takes
> the initial state from the IORef and updates the IORef with the new
> state.
>
>  - Cale
>
> 2009/1/31 guenni68 <[hidden email]>:
>> Hi,
>>
>> in this piece here  
>> http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=1083#a1083
>> I'm trying to create a button that, every time when clicked, increases
>> a counter by one and does a putStrLn of the counters current value.
>>
>> I'm trying to write this without any use of IORef but merely using the
>> state monad.
>>
>> Can anybody show me how to do this?
>>
>> Günther
>>
>> The UI Code is wxHaskell
>> _______________________________________________
>> Haskell-Cafe mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>



--
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Buttons and Clicks - State Monad

Henk-Jan van Tuyl
In reply to this post by Cale Gibbard

Note that, for wxHaskell, you should use Var instead of IORef, to be  
future proof.

Regards,
Henk-Jan van Tuyl


--
http://functor.bamikanarie.com
http://Van.Tuyl.eu/
--


On Sat, 31 Jan 2009 19:38:41 +0100, Cale Gibbard <[hidden email]>  
wrote:

> You might be misunderstanding the purpose of the State Int monad  
> somewhat.
>
> A computation of type State Int a is internally represented by a
> function of type Int -> (Int, a). When you call runState, you
> effectively apply this pure function to an initial state, and get a
> final state and result. You won't be able to do anything with the
> State monad that you couldn't already do with such a function, it's
> more or less a notational convenience.
>
> In particular, the state of your counter will not be preserved between
> calls to runState unless you arrange that the final state returned
> from the last call to runState is passed along as the initial state in
> the next one. Of course, this effectively defeats the purpose of using
> the State monad in the first place.
>
> Since event handlers in wxHaskell must be in the IO monad, there's no
> machinery in place to handle forwarding your state along, so the State
> monad is not terribly useful here. On the other hand, it's rather easy
> to write a function of type State s a -> IORef s -> IO a which takes
> the initial state from the IORef and updates the IORef with the new
> state.
>
>  - Cale
>
> 2009/1/31 guenni68 <[hidden email]>:
>> Hi,
>>
>> in this piece here  
>> http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=1083#a1083
>> I'm trying to create a button that, every time when clicked, increases
>> a counter by one and does a putStrLn of the counters current value.
>>
>> I'm trying to write this without any use of IORef but merely using the
>> state monad.
>>
>> Can anybody show me how to do this?
>>
>> Günther
>>
>> The UI Code is wxHaskell
>> _______________________________________________
>> Haskell-Cafe mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>



--

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe