text: Hi David, that may be also a way to go. I've also looked into this way (view patterns), unfortunately it seems that I will be obliged to maintain 2 parallel structures: for each Event instance, I will have to add a ViewEvent element as well carrying the same information: instance Event Time where eventType = TimeEvent data EventType e where PlayerEvent :: EventType Player MessageEvent :: EventType (Message m) TimeEvent :: EventType Time That's why I like the all-GADT solution... Corentin On Tue, Sep 11, 2012 at 6:46 PM, David Menendez <dave at zednenem.com> wrote: > I'm not sure I understand > > > On Tue, Sep 11, 2012 at 11:06 AM, Corentin Dupont > <corentin.dupont at gmail.com> wrote: > > Yes. > > That's fantastic! This GADT is the missing piece of my puzzle. I > transformed > > a bit your solution, polluting it with some classes instances and > fleshing > > the functions: > > > > data Player = Arrive | Leave deriving (Show, Typeable, Eq) > > data Message m = Message String deriving (Show, Typeable, Eq) > > > > > > data Data a where > > PlayerData :: Int -> Data Player > > MessageData :: m -> Data (Message m) > > > > data Handler where > > Handler :: (Typeable e) => e -> (Data e -> IO ()) -> Handler > > > > instance forall e. (Typeable e) => Typeable (Data e) where > > typeOf _ = mkTyConApp (mkTyCon( ("Expression.EventData (" ++ (show $ > > typeOf (undefined::e))) ++ ")" )) [] > > > > addEvent :: (Typeable e) => e -> (Data e -> IO ()) -> [Handler] -> > [Handler] > > addEvent e h hs = (Handler e h) : hs > > > > triggerEvent :: (Eq e, Typeable e) => e -> Data e -> [Handler] -> IO () > > triggerEvent e d hs = do > > let filtered = filter (\(Handler e1 _) -> e1 === e) hs > > mapM_ f filtered where > > f (Handler _ h) = case cast h of > > Just castedH -> do > > castedH d > > Nothing -> return () > > > > viewEvent :: (Typeable e) => e -> IO() > > > > viewEvent event = do > > case cast event of > > Just (a :: Player) -> putStrLn $ "Player" ++ show a > > > > Nothing -> return () > > case cast event of > > (Just (Message s)) -> putStrLn $ "Player" ++ s > > Nothing -> return () > > > > > > Unfortunately, I still cannot pattern match on the events to view them > > (viewEvent won't compile)... > >> > <> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <>