
Creighton Hogg wrote:
This code is still _really_ ugly, but it does work as far as I've tested
No it's not. It's slightly ugly in places, that's all :) Nice work!
That being said, my first real reactive program was surprisingly simple once I got comfortable with the semantics. The actual reactive code isn't that complicated, but it did take a pretty big shift in thinking from writing explicit game loops.
I have a comment on this point, let me find the exact code: -- This is one of the functions used to convert the event stream of keys -- into an event stream of game state modifiers. It makes me -- fundamentally happy that it can be an entirely pure transformation of -- the state instead of having to live instead a game loop. movePiece :: Key -> Board -> (Piece -> Piece) This is good design, but it's totally orthogonal to the use of reactive. All my conventional imperative haskell GUI programs contain at their core pure values like this (another alternative I sometimes use would be [(Key,Board -> Piece -> Piece)], accessed via Prelude.lookup). They are driven by an imperative scaffold instead of a reactive scaffold but actually isn't particularly hard - the scaffold is thin, the hard work is all in pure values like this. The place where I believe FRP starts to really show its usefulness is in compostionality. The imperative scaffold doesn't compose as well (I don't think) as the reactive scaffold does (I hope!). The interesting challenge to test this, I think, is to add some "modality" to your game. In particular I'm thinking of a "main menu" (that's one mode, different from playing, and presumably has different keybindings in effect), and perhaps a "game over" mode which has some kind of background animation displayed along with your final score and the option to return to the main menu. It's in composing of different modes in this sense that I have begun to find imperative scaffolds clumsy. Jules