<div class="gmail_quote">On Tue, Sep 11, 2012 at 3:39 PM, Corentin Dupontwrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">@Oleg: Yes the set of events is closed and I would be much happier with a GADT! But no matter how hard I tried I couldn&#39;t manage.<br>


Here is the full problem:<br><br><i>{-# LANGUAGE ExistentialQuantification, TypeFamilies, DeriveDataTypeable #-}<br><br>import Data.Typeable<br><br>-- | Define the events and their related data<br>class (Eq e, Typeable e, Show e) =&gt; Event e where<br>


    data EventData e<br><br>-- | Groups of events<br>data PlayerEvent = Arrive | Leave deriving (Typeable, Show, Eq)<br><br>-- | events types<br>data Player          = Player PlayerEvent deriving (Typeable, Show, Eq)<br>

data Message m  = Message String     deriving (Typeable, Show, Eq)<br>
<br>-- | event instances<br>instance Event Player                                      where data EventData Player             = PlayerData {playerData :: Int}<br>instance (Typeable m) =&gt; Event (Message m)   where data EventData (Message m)   = MessageData {messageData :: m}<br>


<br>-- | structure to store an event<br>data EventHandler = forall e . (Event e) =&gt;<br>     EH {eventNumber :: Int,<br>         event :: e,<br>         handler :: (EventData e) -&gt; IO ()} deriving Typeable<br><br>-- store a new event with its handler in the list<br>


addEvent :: (Event e) =&gt; e -&gt; (EventData e -&gt; IO ()) -&gt; [EventHandler] -&gt; [EventHandler]<br>addEvent event handler ehs = undefined<br><br>-- trigger all the corresponding events in the list, passing the </i><i><i>data to the </i>handlers<br>


triggerEvent :: (Event e) =&gt; e -&gt; (EventData e) -&gt; [EventHandler] -&gt; IO ()<br>triggerEvent event edata ehs = undefined<br><br>--Examples:<br>msg :: Message Int<br>msg = Message &quot;give me a number&quot;<br>


myList = addEvent msg (\(MessageData n) -&gt; putStrLn $ &quot;Your number is: &quot; ++ show n) []<br>trigger = triggerEvent msg (MessageData 1) </i><i><i>myList</i> --Yelds &quot;Your number is: 1&quot;</i><br><br>Has you can see this allows me to associate an arbitrary data type to each event with the type family &quot;EventData&quot;. Furthermore some events like &quot;Message&quot; let the user choose the data type using the type parameter. This way I have nice signatures for the functions &quot;addEvent&quot; and &quot;triggerEvent&quot;. The right types for the handlers and the data passed is enforced at compilation time. <br>


But I couldn&#39;t find any way to convert this into a GATD and get rid of the &quot;Event&quot; class......<br></blockquote><div><br></div><div>Would this work?</div><div><br></div><div><font face="courier new, monospace">data Player = Arrive | Leave</font></div>

<div><font face="courier new, monospace">data Message m = Message String</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">data Data a where</font></div><div><font face="courier new, monospace">  PlayerData  :: Int -&gt; Data Player</font></div>

<div><font face="courier new, monospace">  MessageData :: m -&gt; Data (Message m)</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">data Handler where</font></div>

<div><font face="courier new, monospace">  Handler :: Int -&gt; e -&gt; (Data e -&gt; IO ()) -&gt; Handler</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">addEvent :: e -&gt; (Data e -&gt; IO ()) -&gt; [Handler] -&gt; [Handler]</font></div>

<div><font face="courier new, monospace">addEvent = undefined</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">triggerEvent :: e -&gt; Data e -&gt; [Handler] -&gt; IO ()</font></div>

<div><font face="courier new, monospace">triggerEvent = undefined</font></div><div><br></div><div>Regards,</div><div>Sean</div></div>