Dear list,
as you probably know, I'm the author of the reactive-banana package,
which is a library for functional reactive programming (FRP) which can
be used with wxHaskell. As such, I would like to propose a few changes
to wxHaskell which are informed by FRP. Of course, while my primary aim
is to gain better interoperability with my library, I think and hope
that my proposed changes are of independent benefit.
Today, I would like discuss *composable events* and event handlers.
In wxHaskell, event handlers are currently set with the on combinator.
set button [ on command := doSomething ]
Unfortunately, this approach has several problems that don't make it
very composable:
1. Currently, setting an event handler will also *remove* any previous
event handler.
2. The event handler may have have several curried parameters, or even none.
I have found that the most composable approach to events is the
following type
type Event a = AddHandler a
newtype AddHandler a = AddHandler { addHandler :: (a -> IO ()) ->
IO (IO ()) }
Example usage
doSometing :: () -> IO ()
...
removeSomething <- addHandler (on command button) doSomething
The idea is that Event a represents an event that carries data of type
a . If the event does not carry any data, then a = () . The
addHandler function registers an additional event handler with the
event, while keeping the old handlers intact. The return value of
addHandler can be used to remove the event handler again if desired.
(This is how GTK does it, by the way.)
With this type, we can easily define new events from old ones, for instance
instance Functor AddHandler where
fmap f e = AddHandler $ \g -> addHandler e (g . f)
filterJust :: AddHandler (Maybe a) -> AddHandler a
filterJust e = AddHandler $ \g -> addHandler e (maybe (return ()) g)
-- mouse click event
click :: AddHandler Point
click = filterJust . fmap matchClick $ mouse
where
matchClick (MouseLeftDown pt _) = Just pt
matchClick _ = Nothing
Note that this only works well if the event data always given as a
single type, not multiple curried arguments.
I think this is very pleasant. In particular, it cleans up the confusion
about the current crop of write-only events like click and motion .
It also looks a bit like FRP, though it is not powerful emough to become
"true" FRP for reasons I don't want to go into right now.
The main drawback of the AddHandler approach is that we cannot keep
the current syntax
set button [ on click := .. ]
since setting an event handler rightfully implies that the old event
handlers are removed. I'm somewhat undecided about possible solutions,
but we could introduce a new assignment symbol
set button [ on click :+ .. ]
that only works on events.
What do you think?
Best regards,
Heinrich Apfelmus
--
http://apfelmus.nfshost.com
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
wxhaskell-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wxhaskell-devel