F#如何将类型添加到列表中?

时间:2017-05-26 13:52:39

标签: f#

所以我试图用F#为学校项目创建一个纸牌游戏。我来自C#并且在理解F#中的内容方面存在问题。我有类型

Player = {Name : String; Hand : Card list}代表玩家

然后我有里面有牌的牌组。如何将第一张牌从牌组移到玩家手中?在C#中,我将使用类似removeat[i]的内容。

3 个答案:

答案 0 :(得分:6)

let returnFirstElement list =
  match list with
  | h::t -> Some(h),t
  | [] -> None,[]

将你的列表传递给它,它将返回一个元组。第一个值将是您的卡,第二个值是卡的其余部分。 使用Some和None就好像你的牌组中没有卡牌那么你就不会得到一张牌。 由于您来自C#背景,因此将Some视为可空类型,将None视为null。如果您不确定使用它们是非常常见的,请查看F#SomeNone

你可以像

一样使用它
 let (topCard, restOfDeck) = returnFirstElement deckOfCards

如果需要可以给你更多帮助,但这应该是一个足够好的开始。

答案 1 :(得分:2)

要在F#中编写惯用的功能代码,您需要考虑如何明确地模拟系统的状态。每个玩家都有一手牌代表国家的一部分,但我们也需要模拟牌组的状态。

从逻辑上讲,从牌组中抽出会影响牌手和牌组本身。

当牌组中没有牌时,我们还需要考虑错误情况。

这是一个简单的例子,当卡片中没有卡片时,只会出现错误。

type Player = {Name : string; Hand : Card list}

let draw player deck =
    match deck with
    |[] -> invalidArg "deck" "No cards in deck!"
    |drawn::rest -> ({ player with Hand = drawn :: player.Hand }, rest)

您向绘制功能提供了一个Player和一个由Card list表示的套牌,它会返回一个新的Player,其中有一张从牌组中取出的牌和一张新{{1}没有绘制的卡片。

对于某些游戏,你可能最好有两张牌,一张牌,一张牌,一张牌。然后,当你用完卡片时,你可以通过改组丢弃牌来创建一个新牌组。

答案 2 :(得分:-1)

你当然可以在F#中使用任何.Net。这不是惯用的F#,但话说再次,它的递归是多少。基本上,如果要从F#列表中删除元素,可能F#列表不是要使用的最佳集合。您当然可以随时向其filter申请。但如果您的所有商品都是唯一的,请考虑使用套装。

这是一个带有.RemoveAt的版本:

open System.Collections.Generic
let xs = ResizeArray [1;2;3]
xs.RemoveAt(2)

xs

ResizeArray是C#List的同义词。

关于只是移动第一张牌并休息,你可以使用' tail'并且' head'功能。