11

F#を使用すると、リテラルやその他のパタ​​ーンでletバインディングを次のように使用できることに気づきました。

let fib 0 = 1
let exists item [] = false
let car (hd :: tl) = hd
let cdr (hd :: tl) = tl

F#は、次の警告を表示するため、これらの関数を一種のパターンマッチングとして正しく解釈します。

警告1この式のパターンが不完全です。たとえば、値「1」は一致しません

警告2この式のパターンが不完全です。たとえば、値'[_]'は一致しません

これらの関数は期待どおりに機能しますが、完全なパターンマッチングを使用してこのスタイルで関数を定義したいのですが、F#マニュアルでこの代替パターンマッチング構文について何も見つかりません。

使用let whatever = function ...let whatever x = match x with ...て希望の結果を得ることができることはわかっていますが、パターンマッチングのさらに別の構文を発見したばかりであり、使用方法がわからないと永遠に悩まされます。

上記の代替パターンマッチング構文を使用して関数を作成するにはどうすればよいですか?

4

4 に答える 4

12

AFAIK、F#には、同じ名前と異なるパターンマッチング署名を持つ複数のletバインディングを宣言する方法はありません。あなたが探しているものに最も近い構成は、関数ルール式だと思います。

車の場合はこの例を見てください

let car = function
    | hd::tl -> hd
    | [] -> failwith "empty list"
于 2009-01-18T18:25:07.953 に答える
9

JaredPar の言うとおりです。F# には、Haskell がここで行っているような構文形式はありません。

F# 形式は、ほとんどの場合、単一ケースの識別共用体を分割する場合や、一致が不完全な関数を定義する場合に役立ちます (空のリストで失敗する 'car' の例のように)。これは、言語での実質的にすべての名前バインディングがパターンを介して行われるという事実の単なる結果です。この構文形式 (引数にパターンを使用して関数を定義する) は、あなたが説明した正確な理由から、実際にはあまり役に立ちません。

構文形式に関しては、Haskell は ML よりも多くの点で優れていると思いますが、F# のルーツは ML にあります。利点は、F# の優れたサブセットが OCaml とクロスコンパイルできることです (これは、F# 言語とユーザー コミュニティのブートストラップに役立ちました)。欠点は、F# がいくつかの醜い/制限された構文で「立ち往生」していることです。

于 2009-01-18T19:46:35.933 に答える
1

上記の代替パターン マッチング構文を使用して関数を作成するにはどうすればよいですか?

あなたが持っているように、1つのパターンが網羅的である場合にのみ. これが役立つ明白な例には、タプルとレコード、および単一ケースの共用体とアクティブ パターンが含まれます。

この言語機能は、次の場合にいつでも使用できます。

let f(a, b) = ...

したがって、これは次のように一般化されます。

let f(a, (b, c)) = ...

これを使用して、デフォルト値または を選択することもできますSome value:

let def(x, None | _, Some x) = x

ところで、あなたが提案しているスタイルはHaskellの前にSMLで使用され、SMLはMLであるため、これは明らかにHaskellとMLとは何の関係もありません。繰り返しが少ないので、実際には OCaml/F# スタイルを好みます。

fun descriptiveFunctionName [] = true
fun descriptiveFunctionName (_::_) = false

let descriptiveFunctionName = function
  | [] -> true
  | _::_ -> false

これは、自己文書化識別子を使用することに真の価値がある非学術コードに適しています。

于 2012-12-16T14:32:46.530 に答える