2013-08-14 22 views
6

Ho una classe nella mia richiesta - per semplicità supponiamo che è definita in questo modo:Utilizzare una funzione con un argomento di un tipo derivato (F #)

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

Inoltre, ho un sacco di funzioni che accettano oggetti di questo tipo come argomento. Inoltre, alcuni di loro prendono un array di questo tipo:

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

Ora ho capito, che sarebbe stato bello avere un'altra classe che deriva da "BaseType". es .:

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

Tuttavia, non è possibile utilizzare le matrici di tipo ereditario con le funzioni come "myFun"

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

myFun baseArr 
myFun inhArr // won't work 

che sarebbe "bello avere". C'è un modo semplice per riutilizzare le mie funzioni senza applicare tante modifiche?

Suppongo che una delle soluzioni sia quella di mappare il mio array utilizzando ad es. la funzione (divertente (d: inhType) -> d:> baseType), ma mi chiedo se c'è altro da fare.

risposta

9

È necessario annotare la funzione come accettazione di 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! 
+0

Ha funzionato bene per me - grazie :). –

3

È possibile anche compilare una matrice di A con le istanze di un sottotipo, B, utilizzando un tipo di annotazione:

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

Questo potrebbe essere utile per una tantum utilizzo o se la funzione è in una libreria di terze parti. Un altro uso comune è la creazione di matrici in scatola (obj[]).

+2

Vero, ma si noti che questo funziona solo con letterali di array. Qualcosa come 'let bArr: A [] = Array.create 1 (B())' non funzionerà. – kvb