2016-05-07 4 views
7

私は意図的に私はxとyの引数は、まだタイプ」のあることを期待していたこれらの引数がユニット型を持つと推測されたのはなぜですか?

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

、この関数の最後にxを追加しましたが、私が代わりにこの署名を取得する:

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

なぜこれらをユニット型を持つと推論される引数?

編集: 回答には@gillesありがとうございます。次の2つの機能を考慮してください。

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 

2つのシグネチャはどう違うのですか? のは、単純な例を書いてみましょう第二の機能では、コンパイラは、x -either比較の結果を解釈するか、ユニット

答えて

7

としてY-ように思える:複合式で

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

、セミコロンの前の式/改行演算子はユニット型でなければなりません。 「実」値(つまり、ユニット以外のタイプのもの)を持つ式を使用する場合は、明示的に無視するか、変数のないパターンにバインドする必要があります。値は結局、無視され、そのタイプので -

> 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]> 

;前に、任意の型を可能に型付けルールを持つことが可能になります:式の型はunitで統一することができない場合、コンパイラはあなたを思い出させます重要ではありませんが、それは重要な戻り値を誤って破棄することを容易にします。だから、あなたが値を無視したい場合は、明示的に実行します。

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

または

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

私はまた、あなたが 'ignore'を使用して自分自身を見つける場合は、チャンスは、あなたが何か間違ったことをやっていることを追加します。この特定の例は、例外でもありません。戻り値が破棄され、副作用が発生しないため、 'if-then'式は意味を持ちません。 –

関連する問題