2016-05-07 2 views
7

I x stattWarum haben diese Argumente einen Einheitentyp ergeben?

let myMax x y = 
    if x > y then x else y 
    x 

Ich hatte erwartet, dass x und y Argumente sind immer noch von ‚einer Art, aber ich habe diese Signatur an das Ende dieser Funktion absichtlich hinzugefügt:

myMax : x:unit -> y:unit -> unit 

Warum diese Argumente, die auf einen Einheitentyp zurückgeführt werden?

Bearbeiten: Vielen Dank @gilles für die Antwort. Beachten Sie diese zwei Funktionen:

let foo x y = 
    0    // warning 
    x 
val foo : x:'a -> y:'b -> 'a 

let foo2 x y = 
    if x > y then x else y // no warning 
    x 
val foo2 : x:unit -> y:unit -> unit 

Was unterscheidet die beiden Signaturen? scheint in der zweiten Funktion wie der Compiler das Ergebnis des Vergleich -entweder x interpretieren oder y- als Einheit

Antwort

7

Lassen Sie sich ein einfacheres Beispiel schreiben:

> fun x -> x; 0;;   
val it : unit -> int = <fun:[email protected]> 

In einem zusammengesetzten Ausdruck, der Ausdruck vor dem Semikolon Der/newline-Operator muss über den Einheitentyp verfügen. Wenn Sie einen Ausdruck mit einem "echten" Wert verwenden möchten (d. H. Irgendeinen anderen Typ als Einheit), müssen Sie ihn explizit ignorieren oder an ein musterloses Muster binden. Der Compiler erinnert Sie, wenn der Typ des Ausdrucks kann nicht mit unit vereinigt werden:

> fun x -> 0; x;; 

    fun x -> 0; x;; 
    ---------^ 

stdin(7,10): warning FS0020: This expression should have type 'unit', but has type 'int'. 
Use 'ignore' to discard the result of the expression, 
or 'let' to bind the result to a name. 
val it : x:'a -> 'a = <fun:[email protected]> 

Es wäre möglich, eine Typisierung der Regel zu haben, das jede Art vor ; erlaubt - der Wert ignoriert wird, nachdem alle, so seine Art spielt keine Rolle - aber das würde es leicht machen, versehentlich einen wichtigen Rückgabewert zu verwerfen. Also, wenn Sie den Wert ignorieren möchten, tun Sie dies explizit:

let myMax x y = 
    ignore (if x > y then x else y) 
    x 

oder

let myMax x y = 
    let _ = if x > y then x else y 
    x 
+3

würde ich auch hinzufügen, dass, wenn Sie sich unter Verwendung finden 'ignore', die Chancen sind, sind Sie etwas falsch machen . Dieses spezielle Beispiel ist auch keine Ausnahme: Der 'if-then'-Ausdruck macht keinen Sinn, weil sein Rückgabewert weggeworfen wird und keine Nebeneffekte erzeugt. –