我正在尝试编写用于构建专用卡组的递归函数。第一个参数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)

最佳答案

如果要处理currentDeck.Length等于numOfCards的情况,则需要编写:

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)

问题在于,当您编写子句| numOfCards -> (...)时,模式匹配会将currentDeck.Length的值绑定到符号numOfCards(新定义的numOfCards值隐藏了同名的先前值-即您作为参数获取的值) 。

我在上面编写的模式匹配将currentDeck.Length绑定到新符号n,然后检查该n = numOfCards(指的是作为参数传递的numOfCards)。

因此,模式匹配实际上并不是检查相等性的最佳工具-使用普通的if可能更容易编写代码:
let rec buildDungeon (numOfCards, sourceDeck : List<Card>, currentDeck : List<Card>) =
  if currentDeck.Length = numOfCards then currentDeck
  else buildDungeon (numOfCards, sourceDeck, newCard(sourceDeck)::currentDeck)

10-08 00:37