Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Haskell state

Name: Anonymous 2010-04-25 15:36

I've been learning Haskell for more than a month now and I did not have too much trouble understanding monads in general, but the state monad is giving me a headache. I think I have a vague idea how it works, but I am still unable to do the following:



data Point = Point {
    ptX :: Float,
    ptY :: Float }

main = do
    -- create window and register some event handlers
    mainGUI

onWndClick ev do
    let x = eventX ev
    let y = eventY ev
    -- put this point into list

onPaint canvas = do
    -- draw the points from the list


How the hell do I update a list of points in click event handler and draw those points in onPaint? My every attempt failed either with compiler errors or list not updating.

Name: Anonymous 2010-04-25 16:00

onWndClick ev do
Did you forget a =?

Also, you're mixing the IO monad with the State monad. I don't know whether you have to use monad transformers (StateT), or a StateIO monad if there's one, or just State (IO ()).

Name: Anonymous 2010-04-25 16:45

>>2

Yes, I forgot =, it's onWndClick ev = do ...

Thanks for pointing out the need of StateT, found this
http://www.haskell.org/haskellwiki/Simple_StateT_use
I'll take a look at it now and see if it clears out some things for me.

Something else that puzzles me are parameters of state type constructor.


newtype State s a = State (s -> (a, s))


So if I want to keep a list of Points, what should s be? a is obviously [Point].


type PtListState = State ? [Point]

Name: Anonymous 2010-04-25 16:51

>>3
No, s is the type of your state, so it should be [Point]. a is the type returned from an expression after the state is evaluated, and if you don't want to return a value you use () just like you'd do with IO.

You might want to take a look at how State is implemented, to understand better what it actually does.

Name: Anonymous 2010-04-25 17:13

>>4
Ok, thanks for clearing that out. I did take a look at State implementation, but I guess I'll have to do it again and maybe try to expand >>=, runState, get, put etc in samples I found.

Name: Anonymous 2010-04-25 21:02

U
MENA
HASKELL

Name: Anonymous 2010-04-28 4:53

OP here, I just wanted to post the solution if anyone cares... What I needed was IORef monad, not State monad. State monad just "threads" state through computations, you need to pass it from one computation to next and then evaluate at the end, so it's unusable in GUI application with event handlers where you need global state. So, IORef is used like this:


main = do
    pointList <- newIORef []
    -- create window and register some event handlers, pass them pointList
    mainGUI

onWndClick pointList ev do
    let pt = Point (eventX ev) (eventY ev)
    modifyIORef pointList (\pts -> pts ++ [pt])

onPaint canvas pointList = do
    pts <- readIORef pointList
    -- draw the points from the list


I MENA HASKAL

Name: Anonymous 2010-04-28 11:30

>>7
If the order of the points isn’t important, use modifyIORef pointList (pt :) instead. It is less inefficient. Even if the order is important, consider storing the list backwards or using Data.Sequence.Seq instead (which has O(1) append on both ends).

Also I’d like to correct your terminology slightly: IORef is not a monad at all, it is just a data structure usable in the IO monad.

Name: Anonymous 2010-04-28 11:31

>>7
change (\pts -> pts ++ [pt]) to (++ [pt]) or (pt:) and you're good to go.

Name: Anonymous 2010-04-28 12:18

>>7
I recommend the Omae Monad.

Name: Anonymous 2010-04-28 13:02

>>10
Tamae...!!!

Name: Anonymous 2010-04-28 13:03

>>10
[/code][m]
+2 Susscoins for the attention to detail.

Name: Anonymous 2010-04-29 0:43

>>12
Are those redeemable?

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List