6

I've got a class in my application - for simplicity let's assume it's defined like this:

type baseType() =
    member this.A = 5.

Also, I've got a lot of functions that take objects of this type as an argument. Moreover, some of them take an array of this type:

let myFun (xArr : baseType[]) =
    // ... do something inspirig ;)

Now I realized, that it would be nice to have another class which derives from "baseType". e.g.:

type inhType() =
    inherit baseType()
    member this.B = 8.

However, I can't use the arrays of inherited type with the functions like "myFun"

let baseArr = [| baseType() |]
let inhArr = [| inhType() |]

myFun baseArr
myFun inhArr // won't work

which would be "nice to have". Is there a simple way to re-use my functions without applying so many changes ?

I guess one of the solution is to map my array using e.g. the function (fun (d : inhType) -> d :> baseType), but I'm wondering if there's anything else could be done.

LA.27
  • 1,888
  • 19
  • 35

2 Answers2

10

You need to annotate your function as accepting a flexible type.

type A() = class end
type B() = inherit A()

let aArr = [| A() |]
let bArr = [| B() |]

// put # before type to indicate it's a flexible type
let f (x : #A[]) = ()

f aArr
f bArr  // works!
latkin
  • 16,402
  • 1
  • 47
  • 62
3

You can also populate an array of A with instances of a subtype, B, by using a type annotation:

let bArr: A[] = [| B() |]

This could be useful for one-off usage or if the function is in a third party library. Another common usage is creating boxed arrays (obj[]).

Daniel
  • 47,404
  • 11
  • 101
  • 179
  • 2
    True, but note that this only works with array literals. Something like `let bArr : A[] = Array.create 1 (B())` won't work. – kvb Aug 15 '13 at 15:24