fsprojects / FSharp.Control.Reactive

Extensions and wrappers for using Reactive Extensions (Rx) with F#.

Home Page:http://fsprojects.github.io/FSharp.Control.Reactive

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Should Observable.fromEventHandler<'EventArgs> return IObservable<'EventArgs> instead of IObservable<object>?

danien opened this issue · comments

Description

I'm trying to use Observable.fromEventHandler<SomeEventArgs> to create an observable out of an existing EventHandler as below:

    public event EventHandler<SKPaintGLSurfaceEventArgs> PaintSurface;

    let _paintCanvasObservable =
        Observable.fromEventHandler<SKPaintGLSurfaceEventArgs>
            (fun handler -> this.canvasView.PaintSurface.AddHandler(handler))
            (fun handler -> this.canvasView.PaintSurface.RemoveHandler(handler))

But the signature for the function appears to be hardcoded to return an IObservable<object>:

public static IObservable<object> fromEventHandler<EventArgs>(FSharpFunc<EventHandler<object>, Unit> addHandler, FSharpFunc<EventHandler<object>, Unit> removeHandler) where EventArgs : EventArgs

so I get a type mismatch error:

Error FS0001: Type mismatch. Expecting a 'EventHandler<SKPaintGLSurfaceEventArgs>' but given a 'EventHandler<obj>' The type 'SKPaintGLSurfaceEventArgs' does not match the type 'obj' (FS0001)

Repro steps

See example code above.

Expected behavior

Is Observable.fromEventHandler<'EventArgs> intended to return an IObservable<'EventArgs> instead of IObservable<object>? Or am I understanding and using this function incorrectly?

Actual behavior

Observable.fromEventHandler<'EventArgs> returns IObservable<object>, resulting in a type-mismatch error as mentioned above.

Known workarounds

If I modify the fromEventHandler code at https://github.com/fsprojects/FSharp.Control.Reactive/blob/master/src/FSharp.Control.Reactive/Observable.fs#L785 to explicitly specify the 'EventArgs type in the addHandler and removeHandler type parameters,

    let fromEventHandler<'EventArgs when 'EventArgs:> EventArgs>
        //( addHandler    : EventHandler<_> -> unit )
        //( removeHandler : EventHandler<_> -> unit )  =
        ( addHandler    : EventHandler<'EventArgs> -> unit )
        ( removeHandler : EventHandler<'EventArgs> -> unit )  =
        {
            // no other changes.   
        }

the function signature becomes

public static IObservable<EventArgs> fromEventHandler<EventArgs>(FSharpFunc<EventHandler<EventArgs>, Unit> addHandler, FSharpFunc<EventHandler<EventArgs>, Unit> removeHandler) where EventArgs : EventArgs

which is what I need (and expected).

Related information

  • FSharp.Control.Reactive Release 4.2.0
  • Target Framework: Xamarin.Mac Modern
  • Operating system: macOS
  • Visual Studio for Mac 8.4.3. (build 12)

Submitted fix with PR #130.

Is this fixed in 4.3.0?

Yes, it is. Thank you!