In the interest of understanding what's going on I looked up the source code to Event.map, Event.merge and Choice.
type Choice<'T1,'T2> =
| Choice1Of2 of 'T1
| Choice2Of2 of 'T2
[<CompiledName("Map")>]
let map f (w: IEvent<'Delegate,'T>) =
let ev = new Event<_>()
w.Add(fun x -> ev.Trigger(f x));
ev.Publish
[<CompiledName("Merge")>]
let merge (w1: IEvent<'Del1,'T>) (w2: IEvent<'Del2,'T>) =
let ev = new Event<_>()
w1.Add(fun x -> ev.Trigger(x));
w2.Add(fun x -> ev.Trigger(x));
ev.Publish
This means our solution is creating 3 new events.
async {
let merged = Event.merge
(f.KeyDown |> Event.map Choice1Of2)
(f.MouseMove |> Event.map Choice2Of2)
let! move = Async.AwaitEvent merged
}
We could reduce this to one event by making a tightly coupled version of this library code.
type EventChoice<'T1, 'T2> =
| EventChoice1Of2 of 'T1
| EventChoice2Of2 of 'T2
with
static member CreateChoice (w1: IEvent<_,'T1>) (w2: IEvent<_,'T2>) =
let ev = new Event<_>()
w1.Add(fun x -> ev.Trigger(EventChoice1Of2 x))
w2.Add(fun x -> ev.Trigger(EventChoice2Of2 x))
ev.Publish
And here is our new code.
async {
let merged = EventChoice.CreateChoice form.MouseMove form.KeyDown
let! move = Async.AwaitEvent merged
}