3

ここで説明されているように、ORパターンを使用しようとしています:

let foo = function
    | Some (0, x) when x > 0 | None -> "bar"
    | _ -> "baz"

ただし、これによりコンパイラ エラーが発生します。

エラー FS0010: 予期しないシンボル '|' パターンマッチングで。'->' またはその他のトークンが必要です。

私は何を間違っていますか?警備員と関係あるのwhen

4

3 に答える 3

7

ガードは、組み合わせたwhenパターンの数に関係なく、1 つのケースを指します。ケースを分離する必要があります。

let foo = function
  | Some (0, x) when x > 0 -> "bar"
  | None -> "bar"
  | _ -> "baz"

そのため、複雑な式が繰り返されないように、戻り値を除外する方がよい場合があります。

let foo value =
  let ret = "bar"
  match value with
  | Some (0, x) when x > 0 -> ret
  | None -> ret
  | _ -> "baz"

このような繰り返しを避けるもう 1 つの方法は、アクティブなパターンを使用することです。

let (|Bar|_|) = function
  | Some(0, x) when x > 0 -> Some()
  | None -> Some()
  | _ -> None

let foo = function
  | Bar -> "bar"
  | _ -> "baz"
于 2012-06-11T19:34:42.500 に答える
2

x2つのケースは異なる変数のセットをバインドするため(それぞれ、何もバインドしないため)、2つの別々の一致ケースが必要になります。

| Some(0, x) when x>0 -> "bar"
| None -> "bar"
于 2012-06-11T19:36:55.480 に答える
2

非常に複雑なパターンでラベルの特定のバインディングのみを保護したい場合に、私が時々使用する便利なトリックは、独自のアクティブなパターンと&( and) パターン演算子を使用することです。

let (|GreaterThan|_|) lowerLimit n =
    if n > lowerLimit then Some () else None

let (|LesserThan|_|) upperLimit n =
    if n < upperLimit then Some () else None

let (|GreaterOETo|_|) lowerLimit n =
    if n >= lowerLimit then Some () else None

let (|LesserOETo|_|) upperLimit n =
    if n <= upperLimit then Some () else None

let (|InRange|_|) (lowerLimit, upperLimit) n =
    if n >= lowerLimit && n <= upperLimit then Some () else None

let (|Even|Odd|) n =
    if n % 2 = 0 then
        Even (n / 2)
    else
        Odd (n / 2)

type Union =
    | A of int
    | B of int
    | A' of int

let getSpecialCases = function
    | A (Even (x & GreaterThan 4 & LesserOETo 16))
    | A (Odd (x & GreaterThan 0))
    | B (x & LesserOETo 0)
    | A' (Even (x & InRange (5, 16)))
    | A' (Odd (x & GreaterThan 0)) -> Some x
    | _ -> None

もちろん、アクティブなパターン ラッパーへの関数を作成することもできます。

let (|P|_|) pred x =
    if pred x then Some () else None

let ``match`` = function
    | Even (x & pred (fun x -> x >= 7 && x <= 54)) -> Some x
    | _ -> None
于 2012-06-11T19:57:31.523 に答える