Returning derived classes in F#

Viewed 99

Consider the following code, which declares an abstract base class called shape and another class called square which inherits from shape:

open System

[<AbstractClass>]
type shape() =
    abstract area : int

type square(side) =
    inherit shape()
    override this.area = side * side

let return_square(n): shape =
    new square(n)

[<EntryPoint>]
let main argv =
    let foo = new square (3)
    printfn "%d" foo.area

    let bar = return_square(4)
    printfn "%d" bar.area
    0 // Return 0 to OS

The creation of foo works fine, but when I attempt to return a shape from return_square I receive the following error message:

This expression was expected to have type
    'shape'    
but here has type
    'square'

Can anyone shed some light as to what I'm doing wrong? Shouldn't I be able to return a square since it's a type of shape?

Many TIA

1 Answers

The fsharp compiler will not automatically do the cast from square to shape for you.

You can solve this for example by changing your code to:

let return_square(n): shape =
    new square(n) :> shape

or you don't even have to specify the type:

let return_square(n): shape =
    new square(n) :> _

an other alternative is to omit the type from the type signature and only do the cast:

let return_square(n) =
    new square(n) :> shape

Also, the parenthesis and new keyword is not really needed when calling the constructor so you could also simplify it to just:

let return_square n =
    square n :> shape
Related