Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use a function with an argument of a derived type (F#)

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.

like image 482
Alojzy Leszcz Avatar asked Aug 14 '13 22:08

Alojzy Leszcz


2 Answers

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!
like image 176
latkin Avatar answered Sep 20 '22 03:09

latkin


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[]).

like image 43
Daniel Avatar answered Sep 22 '22 03:09

Daniel