2

私はこのような差別された組合を持っています:

type A = |B | C of int*A

次のようにパターン マッチする必要があります (かっこが必要なようです)。

match x with
| B -> printfn "B"
| C (i,a) -> printfn "%A, %A" i a

代わりに、このようにアクティブなパターンのようなものと一致させる方法はありますか:

match x with
| B -> printfn "B"
| C i a -> printfn "%A, %A" i a

そうでない場合、カリー化された引数とのこのマッチングが機能せず、代わりにタプルの使用を強制するように F# が設計されているのはなぜでしょうか?

h::t編集:これは、タプルなどを使わずに使用できる F# リストに触発されたものです。ソースコードは次のようになります。

type List<'T> = 
   | ([])  :                  'T list
   | (::)  : Head: 'T * Tail: 'T list -> 'T list
4

3 に答える 3

3

カリー化された関数とアクティブなパターンの定義を調べると、これが明確になると思います。

カリー化された関数: 複数のパラメーターを受け取りますが、一度に 1 つのパラメーターを渡して、同じことを行うがパラメーターを 1 つ減らす関数を返すことができる関数。例:

let add a b = a + b
//val add : a:int -> b:int -> int
let add5 = add 5
//val add5 : (int -> int)

アクティブ パターン: 解析またはその他の複雑なロジックを使用してマッチングを実行できるパターン マッチングを適用する方法。1 つのパラメーターを取り、解析の結果を返します。したがって、入力 -> 単一の戻り値パラメーター。

//Example taken from https://fsharpforfunandprofit.com/posts/convenience-active-patterns/
let (|Int|_|) str =
   match System.Int32.TryParse(str) with
   | (true,int) -> Some(int)
   | _ -> None
val ( |Int|_| ) : str:string -> int option

関数をカリー化することの要点は、関数を部分的に適用できるようにすることなので、アクティブなパターンの結果に適用すると、その概念はまったく意味がありません。

別の言い方をすれば、カリー化できるのは関数のみであり、アクティブ パターンの結果は関数ではないデータであるため、アクティブ パターンの結果を「カリー化」することはできません。あなたの例では、「C (i,a)」は、関数呼び出しではなく、アクティブ パターン ケースの戻り値の型を定義しています。

于 2016-08-26T15:51:35.210 に答える
2

判別共用体のケースCには、タプル type の値があります(int * A)

(i,a)パターン マッチングの部分はパラメーターではなくiint部分と部分を一致させaていAます。

と同様に一致しC xxのタプルを保持でき(int * A)ます。

于 2016-08-26T15:25:43.880 に答える