1

この 2 つの機能は同じだと思っていましたが、間違っていたようです。2 つの関数 f と g を次のように定義します。

let rec f n k =
   match k with
   |_ when (k < 0) || (k > n) -> 0
   |_ when k = n -> 100
   |_ -> (f n (k+1)) + 1

let rec g n k =
   match k with
   |_ when (k < 0) || (k > n) -> 0
   | n -> 100
   |_ -> (g n (k+1)) + 1

let x = f 10 5
let y = g 10 5

結果は次のとおりです。

val x : int = 105
val y : int = 100

これら2つの機能の違いは何ですか?


編集

なぜここで機能するのですか?

let f x =
   match x with
   | 1 -> 100
   | 2 -> 200
   |_ -> -1

List.map f [-1..3]

そして、私たちは得る

val f : x:int -> int
val it : int list = [-1; -1; 100; 200; -1]
4

2 に答える 2

3

違いは、

match k with 
... 
when k = n -> 100

特定の条件が真の場合に一致するケースです ( k = n)。n条件で使用される は、関数パラメーターとしてバインドされている を参照しますn。一方で

match k with 
...
n -> 100

は、常に成功する可能性kのあるパターン変数に対してのみ一致する必要があるケースです。パターン内の は、関数に渡されたものと同じではありnません。nnn

比較のために、コードを試してください

let rec g n k =
   match k with
   |_ when (k < 0) || (k > n) -> 0
   | n -> n
   |_ -> (g n (k+1)) + 1

2 番目のケースに到達すると、返される値はパターン変数の値であることがわかりますn。これは、の値にバインドされていますk

この動作については、MSDN F# 言語リファレンスの「パターン マッチング」の「変数パターン」セクションで説明されています。

可変パターン

->変数パターンは、一致する値を変数名に割り当てます。変数名は、シンボルの右側の実行式で使用できます。変数パターンだけでも任意の入力に一致しますが、変数パターンは他のパターン内に現れることが多いため、タプルや配列などのより複雑な構造を変数に分解できます。次の例は、タプル パターン内の変数パターンを示しています。

let function1 x =
    match x with
    | (var1, var2) when var1 > var2 -> printfn "%d is greater than %d" var1 var2 
    | (var1, var2) when var1 < var2 -> printfn "%d is less than %d" var1 var2
    | (var1, var2) -> printfn "%d equals %d" var1 var2

function1 (1,2)
function1 (2, 1)
function1 (0, 0)

の使用については、 Match Expressionswhenで詳しく説明しています。

于 2013-09-16T19:31:02.813 に答える
0

最初の関数は問題ありません。それ自体を何度も再帰的に呼び出しn-k、条件と一致すると 100 を返しますwhere k = nn-kしたがって、1回追加してすべての呼び出しを返します。あなたの例ではn=10k=5結果は105でした。

問題は 2 番目の関数です。ここでテストしました。パターンn->100をに変更したz->100ところ、まだ一致しており、再帰的に呼び出されることはありません。したがって、最初の条件で失敗しなければ、常に 100 を返します。F# ではそのような一致は許可されていないと思いますので、必要なものを取得するには条件を設定することをお勧めします。

于 2013-09-16T17:04:47.940 に答える