2

特殊なカードデッキを構築するための再帰関数を作成しようとしています。最初のパラメータであるnumOfCardsは、デッキ内のカードの数であると想定されています。sourceDeckは、デッキを構築するために使用できる可能性のあるカードのリストであり、currentDeckは私のアキュムレータであり、カードの最終的なリストになります。

ただし、私が抱えている問題は、numOfCardsの数値を送信すると、matchステートメントで0に設定されることです。または、少なくともそれがどのように見えるかです。デバッガーでステップスルーしてみましたが、関数に入ると値が正しいです。ただし、一致の実行を開始するとすぐに、一致の値とパラメーターの値(少なくとも一貫性がある)の両方にカーソルを合わせると、突然0になります。

そのため、一致は0でトリガーされ、反復するのではなく、空のcurrentDeckを返すだけです。

これに関するヒントはありますか?おそらく単純なことですが、私は困惑しています。:)

let rec buildDungeon (numOfCards, sourceDeck : List<Card>, currentDeck : List<Card>) =
  match currentDeck.Length with
    | numOfCards  -> currentDeck
    | _           -> buildDungeon (numOfCards, sourceDeck, newCard(sourceDeck)::currentDeck)
4

3 に答える 3

5

If you want to handle a case when currentDeck.Length equals numOfCards then you need to write:

let rec buildDungeon (numOfCards, sourceDeck : List<Card>, currentDeck : List<Card>) =
  match currentDeck.Length with
  | n when n = numOfCards -> currentDeck
  | _ -> buildDungeon (numOfCards, sourceDeck, newCard(sourceDeck)::currentDeck)

The problem is that when you write a clause | numOfCards -> (...), the pattern matching binds the value of currentDeck.Length to the symbol numOfCards (and the newly defined numOfCards value hides the previous value of the same name - that is, the value you got as a parameter).

The pattern matching I wrote above binds currentDeck.Length to a new symbol n and then checks that n = numOfCards (referring to the numOfCards passed as an argument).

So, pattern matching is not really the best tool for checking equality - and your code could be probably more easily written using normal if:

let rec buildDungeon (numOfCards, sourceDeck : List<Card>, currentDeck : List<Card>) =
  if currentDeck.Length = numOfCards then currentDeck
  else buildDungeon (numOfCards, sourceDeck, newCard(sourceDeck)::currentDeck)
于 2012-11-21T23:56:06.107 に答える
1

式のnumOfCards中のmatchは、パラメータの中のものと同じではありません: それは、古い変数を隠している新しい変数です。これは無制限の変数パターンであるため、何にでも一致し、そのものにバインドされます。したがって、最初のパターンが失敗しないため、2 番目の (ワイルドカード) パターンに到達することはありません。

于 2012-11-21T23:55:33.880 に答える
1

F# でのパターン マッチングを理解している限り、使用する必要があります。

let rec buildDungeon (numOfCards, sourceDeck : List<Card>, currentDeck : List<Card>) =
  match currentDeck.Length with
  | n when n = numOfCards -> currentDeck
  | _ -> buildDungeon (numOfCards, sourceDeck, newCard(sourceDeck)::currentDeck)

パターンソートを指定して新規変数を作成する(この例ではn)。すでに定義されているを使用していません。

于 2012-11-22T00:01:58.557 に答える