Consider this:
module Module1 =
type A() = class end
type B() = inherit A()
type C() = inherit A()
let f x = if x > 0 then new B() else new C()
The last line yields an error about type B being expected, but type C being found instead. Ok, I can pretend to understand that: the compiler doesn't know which common base to infer in case there are many.
But guess what? Even when I specify the function type, it still doesn't work:
let f x : A = if x > 0 then new B() else new C()
Now this gives me two errors: "A expected, B found" and "A expected, C found". WTF? Why can't it see that both B and C are implicitly convertible to A?
Yes, I do know that I could use upcast
, like so:
let f x : A = if x > 0 then upcast new B() else upcast new C()
But guess what (again)? upcast
only works in the presence of the explicit function type declaration!
In other words, this:
let f x = if x > 0 then upcast new B() else upcast new C()
still gives an error.
WTF?! Do I really have to add 50% of noise to my program just to help the compiler out? What's with all that hype about F# code being clean and noiseless?
Somehow it feels like this cannot be true. So the question is: am I missing something? How do I make this both compact and working?