FSharp and upcasting for interfaces seem redundant

I have the following code snippet using reactive extensions:

let value : 't = ... Observable.Create<'t>(fun observer -> let subject = new BehaviorSubject<'t>(value) let d0 = subject.Subscribe(observer) let d1 = observable.Subscribe(subject) new CompositeDisposable(d0, d1) :> IDisposable ) 

It works. However, if I drop the upcast in IDisposable, then the code does not work for compilation, citing ambiguous overloads. However, CompositeDisposable is IDisposable. Why can't type inference mechanism solve this? Note. I use this template almost all the time in C #, returning CompositeDisposable from Observable.Create without the need for promotion.

+4
source share
1 answer

As @kvb shows, functions do not support dispersion, so batch conversion is required for interfaces and subclasses.

Here is a small example demonstrating the behavior with subclasses:

 type A() = member xA = "A" type B() = inherit A() member xB = "B" let f (g: _ -> A) = g() let a = f (fun () -> A()) // works let b = f (fun () -> B()) // fails 

If the function f written by you, adding type restrictions can help:

 // This works for interface as well let f (g: _ -> #A) = g() let a = f (fun () -> A()) // works let b = f (fun () -> B()) // works 

Otherwise, you need to perform litle upcast as described in your example.

+8
source

All Articles