What if you have a function that only knows how to operate on squares? Forcing it to accept Rectangles will be unnatural. Of course we can use just a single type Rectangle with two constructors, but inherently that's throwing information away about certain conditions we know to be true.
Even in functional programs when we don't have inheritance, we still sometimes need conversion functions between related types and whether or not these use option types illustrates essentially the same idea:
data Rectangle = Rectangle Int Int
data Square = Square Int
recToSq :: Rectangle -> Maybe Square -- may not succeed; like downcasting
sqToRec :: Square -> Rectangle -- always succeeds; like upcasting
Indeed, this is exactly what the "coercion semantics" in subtyping means: whenever S is a subtype of T, we can generate a total function from S to T. I believe this is also called "inheritance as implicit coercion" in https://www.sciencedirect.com/science/article/pii/0890540191... Quoting from the abstract:> We present a method for providing semantic interpretations for languages with a type system featuring inheritance polymorphism. […] Our goal is to interpret inheritances in Fun via coercion functions which are definable in the target of the translation.