[Haskell-cafe] event handler

Corentin Dupont corentin.dupont at gmail.com
Thu Jun 14 23:04:26 CEST 2012


That look really nice!
Unfortunately I need to have an heterogeneous list of all events with their
handlers.
With this test code it won't compile:

test1 = addEvent (New :: Event Player) (H (undefined::(Player -> IO ()))) []
test2 = addEvent (New :: Event Rule) (H (undefined::(Rule -> IO ()))) test1


On Thu, Jun 14, 2012 at 10:05 PM, Alexander Solla <alex.solla at gmail.com>wrote:

>
>
> 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/9e2300ac/attachment.htm>


More information about the Haskell-Cafe mailing list