问题描述
我是 F# 初学者,目前正在尝试在 BlackJack F# 实现中执行一些 Lists 操作。
我正在尝试对我创建的列表的元素求和,如下所示:
let cardsvalue (k: Cards): List<int> =
match k with
|Ace -> [1;11]
|Two -> [2]
|Three -> [3]
|Four -> [4]
|Five -> [5]
|Six -> [6]
|Seven -> [7]
|Eight -> [8]
|Nine -> [9]
|Ten | Jack | Queen | King -> [10]
type Cards
只是二到九、十到国王和 A 的组合。
所以我需要某种递归函数 CardPoints,它只是添加来自 cardsvalue
的项目,例如 [Two; Three] = [5]
或 [Ace; Ace; Ace] = [3; 13; 23; 33]
表示 Ace 的所有可能值。我尝试了几种获得总和的常用方法,但最终总是出现类型不匹配或不支持运算符错误。例如
let rec CardPoints (cp: List<Cards>): List<int> =
match cp with
| head :: tail -> head + CardPoints tail
| [] -> 0
不接受 + 运算符。
我很想看到这个问题的可能实现。感谢您的时间!
解决方法
我是 F# 初学者
您的代码展示了一种很好的系统方法,并且您已经完成了大部分工作以允许类型系统(和智能感知)帮助解决您的问题。
let cardsvalue (k: Cards): List<int> =
具有完全正确类型签名的有用函数。请注意,它是灰色的。这意味着您没有使用它。
let rec CardPoints (cp: List<Cards>): List<int> =
也完全正确。您正在为类型系统提供尽可能多的帮助,这几乎可以肯定它会发现出现问题的确切点。
我总是以类型不匹配或不支持运算符错误而告终。例如
| head :: tail -> head + CardPoints tail
尝试使用绑定来帮助解决这个问题:
| head :: tail ->
let tailPoints = CardPoints tail
head + tailPoints
您可以告诉(通过将鼠标悬停在它们上方)head
是一个 Cards
,而 tailPoints
是一个 List<int>
。因此,您正在尝试将 Cards
添加到 List<int>
并且没有定义此类加法运算。
所以你把它磨练成一个更小的任务:给定一张卡片(head: Cards
),并给定剩余卡片中可能的分数(tailPoints: List<int>
),你如何找到可能的分数从所有卡片中,哪个应该是 List<int>
?您将需要使用当前未使用的函数 cardsvalue
和另一个小步骤,然后就可以了。
好的,你的答案非常接近。 但是您正在尝试将“卡片”添加到整数列表中。 您想要做的是取卡片的每个可能值并将其添加到其余卡片总和的每个可能值中。
好吧,我可能不会这样做,但也许这是最容易理解的答案(假设您了解列表推导式)。
它在功能上也不是很完美,但我会把它留给你去发现和修复。
let rec cardPoints (cp: List<Card>): List<int> =
match cp with
| head :: tail ->
[ for val1 in cardsvalue head do
for val2 in cardPoints tail do
val1 + val2 ]
| [] -> [0]