Hi Alexander,<br>sorry my initial example was maybe misleading. What I really what to do is to associate each event with an arbitrary data type. For example, consider the following events:<br>NewPlayer<br>NewRule<br>Message<br>
User<br><br>I want to associate the following data types with each, to pass to there respective handlers:<br>NewPlayer ---&gt; Player<br>
NewRule ---&gt; Rule<br>
Message ---&gt; String<br>
User ---&gt; String<br><br>Message and User have the same data type associated, that&#39;s why we can&#39;t use this type as a key to index the event...<br><br><br><div class="gmail_quote">On Sun, Jun 17, 2012 at 12:04 AM, 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 class="im">On Fri, Jun 15, 2012 at 1:59 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">



I made some modifications based on your suggestions (see below).<br>I made a two parameters class:<br>
<i>class (Typeable e, Typeable d) =&gt; Handled e d </i><br>Because after all what I want is to associate an event with its type parameters.<br></blockquote><div><br></div></div><div>I think our approaches are diverging.  In particular, I don&#39;t think you want to use both</div>
<div class="im">


<div><br></div><div>newPlayer :: Event Player</div><div>newRule    :: Event Rule</div><div><br></div></div><div>and also</div><div><br></div><div>data NewPlayer</div><div>data NewRule</div><div><br></div><div>without a very good reason.  These are representations of the same relationship (the attachment/joining of &quot;New&quot; Event semantics to a Player or Rule) at different levels in the abstraction hierarchy.  All Handled e d type class is doing is attempting to (1) constrain some types, (2) &quot;equate&quot;/join NewPlayer and newPlayer (as far as I can see), which would be unnecessary without either NewPlayer or newPlayer.  That said, you can definitely have a good reason I&#39;m not aware of.</div>



<div><br></div><div>So what is your use case for NewPlayer, for example?</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I don&#39;t know why I cannot implement you suggestion to restrict the instances of Event:<br>





<i>data </i><i>(Handled e d) =&gt; </i><i>Event e = Event deriving (Typeable, Eq) <br></i>gives me a <br><i>Not in scope: type variable `d&#39;</i></blockquote><div><br></div></div><div>Yeah, that&#39;s undecidable.  What would happen if you had</div>




<div><br></div><div>instance Handled New    Player</div><div>instance Handled New    Rule</div><div><br></div><div>and you tried to make an (Event Player)?  The compiler couldn&#39;t decide between the instances.  In principle, functional dependencies (or type families, as you mentioned) would make d depend on e uniquely, but I don&#39;t think the data declaration is smart enough to figure it out, since it appears to be using scoping rules to deal with the possibility of undecidability.  If you want to try, the syntax would be:</div>




<div><br></div><div>{-# LANGUAGE FunctionalDependencies #-}</div><div>class Handled e d | e -&gt; d where -- ...</div><div><br></div><div>Of course, apparently the situation with multiple conflicting instances &quot;should&quot; never happen if you use NewPlayer and NewRule and so on.  But that compiler can&#39;t know it unless you tell it somehow.</div>
<div class="im">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


But apart from that it works very well! It&#39;s quite a nice interface!<br>
Also just to know, is there a way of getting ride of all these &quot;Typeable&quot;?<br></blockquote><div><br></div></div><div>Yes, but you would just be re-inventing the wheel.</div><div><br></div><div>I pretty much constantly keep &quot;deriving (Data, Eq, Ord, Show, Typeable)&quot; in my clipboard.  I don&#39;t use Typeable (or Data), but useful libraries do.  For example, SafeCopy.</div>
<div class="im">



<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="gmail_quote">I mean that I have events like:<br>




Message String<br>UserEvent String<br>That have a &quot;data&quot; of the same type, but they are not related.<br></div></blockquote><div><br></div></div><div>Using my old version of the code for reference, nothing is stopping you from doing:</div>




<div><br></div><div>data Event e = New | Message String | User String </div><div><div class="h5"><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>{-# LANGUAGE ExistentialQuantification, DeriveDataTypeable, MultiParamTypeClasses #-}<br>



<br><i>module Events (addEvent, newPlayer, newRule) where<br>
<br>import Control.Monad<br>import Data.List<br>import Data.Typeable<div><br><br>newtype Player = P Int deriving Typeable <br>newtype Rule = R Int deriving Typeable<br></div>data Event e = Event deriving (Typeable, Eq)<br>




<br>data NewPlayer deriving Typeable<br>
data NewRule deriving Typeable<br><br>newPlayer :: Event NewPlayer<br>newPlayer = Event<br>newRule :: Event NewRule<br>newRule = Event<br><br>class (Typeable e, Typeable d) =&gt; Handled e d <br>instance Handled NewPlayer Player<br>





instance Handled NewRule Rule<br><br>data EventHandler = forall e d . (Handled e d) =&gt; EH (Event e) (d -&gt; IO ()) <br><br>addEvent :: (Handled e d) =&gt; Event e -&gt; (d -&gt; IO ()) -&gt; [EventHandler] -&gt; [EventHandler] <br>




<div>
addEvent e h ehs = (EH e h):ehs<br> <br></div>triggerEvent :: (Handled e d) =&gt; Event e -&gt; d -&gt; [EventHandler] -&gt; IO ()<div><br>triggerEvent e d ehs = do<br>    let r = find (\(EH myEvent _) -&gt; cast e == Just myEvent) ehs<br>





    case r of<br>       Nothing -&gt; return ()<br></div>       Just (EH _ h) -&gt; case cast h of<div><br>        Just castedH -&gt; castedH d<br>        Nothing -&gt; return ()<br><br></div>-- TESTS<div>
<br>h1 :: Player -&gt; IO ()<br>h1 (P a) = putStrLn $ &quot;Welcome Player &quot; ++ (show a) ++ &quot;!&quot;<br>
h2 :: Rule -&gt; IO ()<br>h2 (R a) = putStrLn $ &quot;New Rule &quot; ++ (show a)<br></div>eventList1 = addEvent newPlayer h1 []<br>eventList2 = addEvent newRule h2 eventList1<br><br>trigger1 = triggerEvent newPlayer (P 1) eventList2 --Yelds &quot;Welcome Player 1!&quot; <br>





trigger2 = triggerEvent newRule (R 2) eventList2 --Yelds &quot;New Rule 2&quot; </i><br><br></blockquote><br></div></div></div>
</blockquote></div><br>