In order to understand the cause of your confusion you should not go anywhere further, than the first statement of the link you referred to :
A sequence is a logical series of elements all of one type.
You can return a sequence of only one, the same type like seq<A>
, or seq<obj>
. The OOP-ish fact that types B
and C
are inherited from A
is not relevant. The following may help: all your instances are also inherited from obj
, but in order to make from them a seq<obj>
you should explicitly cast:
// Works fine
let testSeq = seq<obj> {
yield A(0) :> obj
yield B(1) :> obj
yield C(2) :> obj
}
or just box
them like below:
// Works fine too
let testSeq = seq {
yield box (A(0))
yield box (B(1))
yield box (C(2))
}
EDIT: For understanding the reasoning behind explicit casting in F# the following (simplistic) consideration may help. Type inference does not do guessing; unless it can derive seq
type deterministically, or have it explicitly declared, it will complain.
If you just do
let testSeq = seq {
yield A(0)
yield B(1)
yield C(2)
}
compiler is presented with indeterminism - testSeq
can be either seq<A>
, or seq<obj>
, so it complains. When you do
let testSeq = seq {
yield A(0)
yield upcast B(1)
yield upcast C(2)
}
it infers testSeq
as seq<A>
based on type of the first member and upcasts B and C to A
without complaining. Similarly, if you do
let testSeq = seq {
yield box A(0)
yield upcast B(1)
yield upcast C(2)
}
it will infer testSeq
as seq<obj>
based on the type of the first member upcasting this time second and third members to obj
, not A
.