2014-11-27 17 views
8

Qualcuno può spiegare questa curiosità F #?Argomenti ripetuti nelle interfacce

type IFoo = 
     abstract member Bar1: int * int -> int * int 
     abstract member Bar2: int * int -> (int * int) 
     abstract member Bar3: (int * int) -> int * int 

    type Foo() = class end 
     with 
     interface IFoo with 
      member this.Bar1 (x, y) = (x, y) 
      member this.Bar2 (x, y) = (x, y) // Same impl as Bar1 i.e. parentheses on RHS of -> in interface member definition are ignored 
      // member this.Bar3 (x, y) = (x, y) // Compile error: "This override takes a different number of arguments to the corresponding abstract member" 
      member this.Bar3 tuple = tuple // So, parentheses on LHS of -> in interface member definition *does* make a difference! 

Qual è la differenza di significato tra le definizioni di IFoo.Bar1 e IFoo.Bar3?

risposta

9

Qui, il tipo di input può descrivere due cose diverse: una tupla o l'elenco di argomenti di un metodo CLI.

Questo non fa alcuna differenza sul tipo di ritorno, poiché l'unica interpretazione di questo tipo di ritorno è una tupla. Ma sulla lista degli argomenti, puoi decidere tra un metodo CLI che accetta due argomenti, o un metodo CLI che accetta un argomento, che sembra essere una tupla. Quest'ultimo è indicato dalle parentesi in più.

Ecco perché è possibile implementare Bar3 con un singolo argomento, digitato come una tupla, che non è possibile con gli altri (a partire da F # 3).

Questo è anche un luogo in cui le doppie parentesi fanno la differenza per le singole parentesi. Se Bar3 non fosse astratto, potresti applicare l'input di tupla dichiarandolo come member this.Bar3 ((arg1, arg2)).

Gli elenchi di argomenti del metodo presentano funzionalità aggiuntive, come gli argomenti facoltativi. Quindi:

type Test() = 
    member t.BarA(a, ?b) = a 
    member t.BarT((a, ?b)) = a // Error 

L'ultima riga dà l'errore "Argomenti facoltativi sono ammessi solo i membri di tipo", dal momento che b è ora parte di un modello tupla, non un argomento in lista l'argomento del metodo.

+0

Interessante: i dettagli della CLI stanno perdendo nella sintassi F #. Immagino che sia necessario per motivi di interoperabilità? Per il puro codice F #, non vedo alcun motivo per distinguere i due casi. – Akash

+1

@Akash Non importa perché, il mondo dei metodi CLI è diventato una parte di F # come linguaggio multi-paradigma. Ha sovraccarico, ereditarietà e override, argomenti opzionali e così via, e queste funzionalità non sono considerate esclusive per l'interoperabilità nel modo in cui è null. Ma non sempre si combinano bene con la programmazione funzionale-prima. Nel puro codice funzionale, queste funzioni non sono utilizzate, quindi la parte funzionale si adatta bene ai metodi CLI, fatta eccezione per il raro disagio mostrato nella domanda. – Vandroiy

Problemi correlati