Re: [Haskell-cafe] Mitigating state-threading through an application loop

2011-12-21 Thread wren ng thornton

On 12/20/11 11:08 AM, Michael Serra wrote:

Hello Haskellers,
   I'm implementing a simple tree-manipulating (for sports tournaments)
application prototype, with SDL for graphics and simple user interaction.
For reference, I've posted the code on hpaste.http://hpaste.org/55506
My question is about code organization: everything was simple and elegant
until I started writing the program's display/event loop.  Every function
in this section has to be passed the same parameters - the application
window to draw on, the font to display text with, the tree representing the
current application state, etc.  The font is an especially egregious
example of the problem, because it's only used by one function but to get
there it must be threaded through all of them (looking at the hpaste, you
will see I don't want to call openFont on every invocation of drawTexts;
what's needed is to call it once in main and have the resulting value
available to drawTxt.  So my question: how can I mitigate the ugliness of
this state-threading?  I understand this is one purpose for monads; am I
supposed to implement a monad transformer for this?


I haven't looked at your specific example (for which I think the 
previous emails provide the answer you're seeking), but here's a general 
technique which I often use to help clarify things...


Oftentimes I find that the kinds of state needed for various functions 
are disjoint (or nearly so), and so packaging it all up in a State monad 
just doesn't feel right. But remember that functions are data too! In 
your main/driver function, grab all the kinds of state and pass them in 
to the various functions which need them. Now, instead of passing the 
arguments around in your State, just pass a record containing all the 
partially applied functions.


This works best when you know the basic API you want (it's specified by 
the record's type), but there are a bunch of different ways to get 
there. It's especially helpful when you have both pure and 
side-effecting ways to get there, or when the side-effects are 
concentrated in getting the parameters rather than in using them (e.g., 
dealing with commandline arguments).


--
Live well,
~wren

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Mitigating state-threading through an application loop

2011-12-20 Thread Michael Serra
Hello Haskellers,
  I'm implementing a simple tree-manipulating (for sports tournaments)
application prototype, with SDL for graphics and simple user interaction.
For reference, I've posted the code on hpaste. http://hpaste.org/55506
My question is about code organization: everything was simple and elegant
until I started writing the program's display/event loop.  Every function
in this section has to be passed the same parameters - the application
window to draw on, the font to display text with, the tree representing the
current application state, etc.  The font is an especially egregious
example of the problem, because it's only used by one function but to get
there it must be threaded through all of them (looking at the hpaste, you
will see I don't want to call openFont on every invocation of drawTexts;
what's needed is to call it once in main and have the resulting value
available to drawTxt.  So my question: how can I mitigate the ugliness of
this state-threading?  I understand this is one purpose for monads; am I
supposed to implement a monad transformer for this?

I think it would be great if I could define a type AppState as a tuple of
the various things I need to thread, and specify some kind of automatic
as-pattern, so that every function taking this AppState parameter would
implicitly have its components bound to certain preset names.  I've never
seen anyone do this however.  What is the right solution?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Mitigating state-threading through an application loop

2011-12-20 Thread Vo Minh Thu
2011/12/20 Michael Serra mk.se...@gmail.com:
 Hello Haskellers,
   I'm implementing a simple tree-manipulating (for sports tournaments)
 application prototype, with SDL for graphics and simple user interaction.
 For reference, I've posted the code on hpaste.  My question is about code
 organization: everything was simple and elegant until I started writing the
 program's display/event loop.  Every function in this section has to be
 passed the same parameters - the application window to draw on, the font to
 display text with, the tree representing the current application state,
 etc.  The font is an especially egregious example of the problem, because
 it's only used by one function but to get there it must be threaded through
 all of them (looking at the hpaste, you will see I don't want to call
 openFont on every invocation of drawTexts; what's needed is to call it once
 in main and have the resulting value available to drawTxt.  So my question:
 how can I mitigate the ugliness of this state-threading?  I understand this
 is one purpose for monads; am I supposed to implement a monad transformer
 for this?

 I think it would be great if I could define a type AppState as a tuple of
 the various things I need to thread, and specify some kind of automatic
 as-pattern, so that every function taking this AppState parameter would
 implicitly have its components bound to certain preset names.  I've never
 seen anyone do this however.  What is the right solution?

You can use the -XRecordWildcards extension[0] with a Reader or a State monad.

  data AppState = AppState { appStateSomething :: String }

  f AppState{..} = print appStateSomething

Cheers,
Thu

[0] 
http://haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#record-wildcards

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Mitigating state-threading through an application loop

2011-12-20 Thread Antoine Latter
On Tue, Dec 20, 2011 at 11:08 AM, Michael Serra mk.se...@gmail.com wrote:
 Hello Haskellers,
   I'm implementing a simple tree-manipulating (for sports tournaments)
 application prototype, with SDL for graphics and simple user interaction.
 For reference, I've posted the code on hpaste.  My question is about code
 organization: everything was simple and elegant until I started writing the
 program's display/event loop.  Every function in this section has to be
 passed the same parameters - the application window to draw on, the font to
 display text with, the tree representing the current application state,
 etc.  The font is an especially egregious example of the problem, because
 it's only used by one function but to get there it must be threaded through
 all of them (looking at the hpaste, you will see I don't want to call
 openFont on every invocation of drawTexts; what's needed is to call it once
 in main and have the resulting value available to drawTxt.  So my question:
 how can I mitigate the ugliness of this state-threading?  I understand this
 is one purpose for monads; am I supposed to implement a monad transformer
 for this?

 I think it would be great if I could define a type AppState as a tuple of
 the various things I need to thread, and specify some kind of automatic
 as-pattern, so that every function taking this AppState parameter would
 implicitly have its components bound to certain preset names.  I've never
 seen anyone do this however.  What is the right solution?


I've done that before in web-apps. It is conventional enough.

To ease the threading-through of paramters you can use a Reader monad
(perhaps ReaderT AppState IO). I don't know how well this fits in with
the SDL libraries, though.

Antoine

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe