Hi,<br>I designed my event engine like this:<br><span style="font-family:courier new,monospace"><br>-- | events types<br>data Player = Arrive | Leave deriving (Typeable, Show, Eq)<br>data RuleEvent = Proposed | Activated | Rejected | Added | Modified | Deleted deriving (Typeable, Show, Eq)<br>
data Time deriving Typeable<br>data InputChoice c deriving Typeable<br>(...)<br><br>-- | events names<br>data Event a where<br> Player :: Player -> Event Player<br> RuleEv :: RuleEvent -> Event RuleEvent<br>
Time :: UTCTime -> Event Time<br> InputChoice :: (Eq c, Show c) => PlayerNumber -> String -> [c] -> c -> Event (InputChoice c)<br>(...)<br><br>-- | data associated with each events<br>data EventData a where<br>
PlayerData :: {playerData :: PlayerInfo} -> EventData Player<br> RuleData :: {ruleData :: Rule} -> EventData RuleEvent<br> TimeData :: {timeData :: UTCTime} -> EventData Time<br>
InputChoiceData :: (Show c, Read c, Typeable c) => {inputChoiceData :: c} -> EventData (InputChoice c)<br>(...)<br><br>-- associate an event with an handler<br>data EventHandler where<br> EH :: (Typeable e, Show e, Eq e) =><br>
{eventNumber :: EventNumber,<br> event :: Event e,<br> handler :: (EventNumber, EventData e) -> Exp ()} -> EventHandler<br><br>--execute all the handlers of the specified event with the given data<br>
triggerEvent :: (Typeable a, Show a, Eq a) => Event a -> EventData a -> [EventHandler] -> State Game ()<br> </span><br><br>I use a type parameter "e" on Event and EventData to be sure that the right data is shuffled to the right event handler. <br>
It worked well until now. But now I'm hitting a wall with the GUI, because the data sent back for InputChoice can only be a String.<br>So, I need to call triggerEvent with: <span style="font-family:courier new,monospace">Event(InputChoice String)</span> and <span style="font-family:courier new,monospace">EventData (InputChoice String)</span>...<br>
Which doesn't work obviously because the types are not the same than initially (for example, the event was built with <span style="font-family:courier new,monospace">Event(InputChoice Bool)</span>).<br><br>Cheers,<br>
C<br><br><br><br><br><div class="gmail_quote">On Wed, Oct 24, 2012 at 7:25 PM, Stephen Tetley <span dir="ltr"><<a href="mailto:stephen.tetley@gmail.com" target="_blank">stephen.tetley@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Corentin<br>
<br>
It looks like you are writing the event handler on the server side. If<br>
so, the range of events you can handle is fixed to just those you<br>
implement handlers for - having an openly extensible event type is<br>
useless if this is the case.<br>
<br>
Ignoring client/server for a moment, a function (State -> State) would<br>
be the most "extensible" API you could allow for clients. You don't<br>
need to worry about an open set of Event types, a client knows the<br>
state exactly and doesn't need extensibility.<br>
<br>
Client/Server operation won't allow a state transformer API as Haskell<br>
can't readily serialize functions. But you can implement a "command<br>
language" enumerating state changing operations. The second Quickcheck<br>
paper gives a very good example of how to implement such a command<br>
language.<br>
<br>
<br>
Testing Monadic Code with QuickCheck (2002)<br>
Koen Claessen , John Hughes<br>
<a href="http://www.cse.chalmers.se/~rjmh/Papers/QuickCheckST.ps" target="_blank">www.cse.chalmers.se/~rjmh/Papers/QuickCheckST.ps</a><br>
<br>
Or Citeseer if you need a PDF:<br>
<a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.9275" target="_blank">http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.9275</a><br>
<div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br>