That look really nice!<br>Unfortunately I need to have an heterogeneous list of all events with their handlers.<br>With this test code it won&#39;t compile:<br><br>test1 = addEvent (New :: Event Player) (H (undefined::(Player -&gt; IO ()))) []<br>
test2 = addEvent (New :: Event Rule) (H (undefined::(Rule -&gt; IO ()))) test1<br><br><br><div class="gmail_quote">On Thu, Jun 14, 2012 at 10:05 PM, Alexander Solla <span dir="ltr">&lt;<a href="mailto:alex.solla@gmail.com" target="_blank">alex.solla@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br><br><div class="gmail_quote"><div><div class="h5">On Thu, Jun 14, 2012 at 12:15 PM, Corentin Dupont <span dir="ltr">&lt;<a href="mailto:corentin.dupont@gmail.com" target="_blank">corentin.dupont@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi folks,<br>I&#39;m trying to make a simple event driven engine. It simply consists of two functions:<br>- &quot;addEvent&quot;, where you pass the event name with a callback, <br>- &quot;triggerEvent&quot; where you pass the event name with the data. <br>


the data shall be passed to the callback of the corresponding event.<br><br>I have trouble making it correctly typed.<br>Here is my try:<br><i><br>type Player = Int  --dummy types for the example<br>type Rule = Int<br>data EventEnum = NewPlayer | NewRule deriving Eq<br>


data Data = P Player | R Rule<br>data Handler = H (Data -&gt; IO ())<br><br>addEvent :: EventEnum -&gt; Handler -&gt; [(EventEnum, Handler)] -&gt; [(EventEnum, Handler)]<br>addEvent e h es = (e,h):es<br><br>triggerEvent :: EventEnum -&gt; Data -&gt; [(EventEnum, Handler)] -&gt; IO ()<br>


triggerEvent e d es = do<br>           let r = lookup e es<br>    case r of <br>                      Nothing -&gt; return ()<br>                      Just (H h) -&gt; h d</i><br><br>The trouble is that I want the user to be only able to add an event that is compatible with its handler:<br>


For example the event NewPlayer should have a handler of type Player -&gt; IO (). The data passed when triggering this event should be only of type Player.<br>How can I do that? It sound like dependant typing...<br><br></blockquote>

<div><br></div></div></div><div>Haven&#39;t tried it, and I don&#39;t know if it actually does what you want in the big picture.  But you can do &quot;dynamic&quot; dependent typing with dummy (free) type variables.</div>
<div><br></div>
<div><i><div class="im">type Player = Int  --dummy types for the example<br>type Rule = Int<br></div>data Event d = New deriving Eq -- not necessary for this example, but you might want to enumerate other events.<br><br>
</i></div><div><i>class Handled data where -- Corresponds to your &quot;Data&quot; type<br>
<br></i></div><div><i>data Handler d = H (d -&gt; IO ())</i></div><div><i><br></i></div><div><i>instance Handled Player</i></div><div><i>instance Handled Rule</i></div><div><i><br></i></div><div><i>addEvent :: (Handled d) =&gt; Event d -&gt; Handler d -&gt; [(Event d, Handler d)] -&gt; [(Event d, Handler)]</i></div>

<div><i>triggerEvent :: (Handled d) =&gt; Event d -&gt; d -&gt; [(Event d, Handler d)] -&gt; IO ()</i></div><div><i><br></i></div><div>Basically, this means that Events are &quot;keyed&quot; into separate spaces by the Handled types.  (New :: Event Player) has a different type as (New :: Event Rule).</div>

<div><br></div><div>You might want to look into ScopedTypeVariables.</div></div>
</blockquote></div><br>