In your example, you say that you have a list of elephants - which is true in this case - but the type of l
is really a list of Thing
values and so it can contain both elephants and eagles. This is why you need to use pattern matching - to handle all possible cases.
If you regularly need to use list that contain only elephants, then it might make sense to define a separate type of elephants. Something like:
type ElephantInfo = { Size : int }
type Thing =
| Elephant of ElephantInfo
| Eagle
Now you can create a list of type list<ElephantInfo>
which can contain just elephants and so you don't need pattern matching:
let l1 = [ {Size=1}; {Size=2} ]
for el in l1 do printfn "%d" el.Size
On the other hand, if you want to mix elephants and eagles, you'll create list<Thing>
and then use pattern matching:
let l2 = [ Elephant {Size=1}; Eagle ]