[Haskell-cafe] type variable in class instance
David Menendez
dave at zednenem.com
Tue Sep 11 18:46:57 CEST 2012
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)...
Mixing GADTs and Typeable seems like a bad idea. If you really don't
want to put viewEvent in the Event typeclass, but the class of events
is closed, you could use a GADT to witness the event type.
class Event e where
eventType :: EventType e
...
data EventType e where
PlayerEvent :: EventType Player
MessageEvent :: EventType (Message m)
viewEvent :: Event e => e -> IO ()
viewEvent = viewEvent' eventType
viewEvent' :: EventType e -> e -> IO ()
viewEvent' PlayerEvent e = ...
viewEvent' MessageEvent (Message s) = ...
--
Dave Menendez <dave at zednenem.com>
<http://www.eyrie.org/~zednenem/>
More information about the Haskell-Cafe
mailing list