[Haskell-cafe] event handler

Alexander Solla alex.solla at gmail.com
Thu Jun 14 22:05:33 CEST 2012


On Thu, Jun 14, 2012 at 12:15 PM, Corentin Dupont <corentin.dupont at gmail.com
> wrote:

> Hi folks,
> I'm trying to make a simple event driven engine. It simply consists of two
> functions:
> - "addEvent", where you pass the event name with a callback,
> - "triggerEvent" where you pass the event name with the data.
> the data shall be passed to the callback of the corresponding event.
>
> I have trouble making it correctly typed.
> Here is my try:
> *
> type Player = Int  --dummy types for the example
> type Rule = Int
> data EventEnum = NewPlayer | NewRule deriving Eq
> data Data = P Player | R Rule
> data Handler = H (Data -> IO ())
>
> addEvent :: EventEnum -> Handler -> [(EventEnum, Handler)] -> [(EventEnum,
> Handler)]
> addEvent e h es = (e,h):es
>
> triggerEvent :: EventEnum -> Data -> [(EventEnum, Handler)] -> IO ()
> triggerEvent e d es = do
>     let r = lookup e es
>     case r of
>        Nothing -> return ()
>        Just (H h) -> h d*
>
> The trouble is that I want the user to be only able to add an event that
> is compatible with its handler:
> For example the event NewPlayer should have a handler of type Player -> IO
> (). The data passed when triggering this event should be only of type
> Player.
> How can I do that? It sound like dependant typing...
>
>
Haven't tried it, and I don't know if it actually does what you want in the
big picture.  But you can do "dynamic" dependent typing with dummy (free)
type variables.

*type Player = Int  --dummy types for the example
type Rule = Int
data Event d = New deriving Eq -- not necessary for this example, but you
might want to enumerate other events.

*
*class Handled data where -- Corresponds to your "Data" type

*
*data Handler d = H (d -> IO ())*
*
*
*instance Handled Player*
*instance Handled Rule*
*
*
*addEvent :: (Handled d) => Event d -> Handler d -> [(Event d, Handler d)]
-> [(Event d, Handler)]*
*triggerEvent :: (Handled d) => Event d -> d -> [(Event d, Handler d)] ->
IO ()*
*
*
Basically, this means that Events are "keyed" into separate spaces by the
Handled types.  (New :: Event Player) has a different type as (New :: Event
Rule).

You might want to look into ScopedTypeVariables.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120614/e7a41377/attachment.htm>


More information about the Haskell-Cafe mailing list