In order to understand what was going on, I searched for the source code for EventMap, 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(fx)); 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 that our solution creates 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 a single event by creating 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 }
gradbot
source share