我正在尝试编写一个用于构建专用卡片组的递归函数。第一个参数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)
答案 0 :(得分:5)
如果您想在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
绑定到 new 符号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)
答案 1 :(得分:1)
numOfCards
表达式中的match
与参数中的{{1}}不同:它是阴影旧表达式的新变量。因为它是一个无界的变量模式,它将匹配任何东西并将自己绑定到那个东西。因此,永远不会达到第二个(通配符)模式,因为第一个模式永远不会失败。
答案 2 :(得分: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)。您没有使用已定义的。