2013-08-14 12 views
6

ich eine Klasse in meiner Anwendung haben - der Einfachheit halber wollen wir es annehmen, wie folgt definiert:eine Funktion mit einem Argument von einem abgeleiteten Typ (F #) verwenden

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

Außerdem habe ich eine Menge bekam von Funktionen, die Objekte dieses Typs als Argument verwenden. Darüber hinaus nehmen einige von ihnen eine Reihe von dieser Art:

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

Jetzt erkannte ich, dass es schön wäre, eine andere Klasse zu haben, die von „basetype“ leitet. z.B .:

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

Allerdings kann ich verwenden, um die Anordnungen von ererbten Typ mit den Funktionen wie "myfun" nicht

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

myFun baseArr 
myFun inhArr // won't work 

die "nice to have" sein würde. Gibt es eine einfache Möglichkeit, meine Funktionen wieder zu verwenden, ohne so viele Änderungen vorzunehmen?

Ich denke, eine der Lösung besteht darin, mein Array mit z. die Funktion (Spaß (d: inhType) -> d:> baseType), aber ich frage mich, ob noch etwas getan werden könnte.

Antwort

9

Sie müssen Ihre Funktion als eine flexible type akzeptieren annotieren.

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! 
+0

Arbeitete gut für mich - danke :). –

3

Sie auch eine Reihe von A mit Instanzen eines Subtyp bevölkern können, B, durch eine Typanmerkung verwendet:

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

Diese für einmalige Nutzung oder wenn die Funktion nützlich sein könnte, ist in einer Drittanbieter-Bibliothek. Eine andere häufige Verwendung ist das Erstellen von Box-Arrays (obj[]).

+2

True, aber beachten Sie, dass dies nur mit Array-Literalen funktioniert. Etwas wie 'let bArr: A [] = Array.create 1 (B())' wird nicht funktionieren. – kvb