如何在代码内联的 f# 中以惯用方式生成数据
How to generate data idiomatically in f# inline in code
假设我正在尝试在 f# 中实现某种扑克牌程序。首先是类型系统的正确使用,这里是大量的新手。
type Suit =
| Hearts
| Diamonds
| Spades
| Clubs
type Card = {
Suit:Suit
Rank:int
}
type Hand = {
Cards:List<Card>
}
无论如何,假设我想要一个函数来 return 给我一个可能持有卡片的随机列表。我想我会把两个函数链接在一起,但是我很难在不创建大量对象的情况下实现它们。 list 模块中的每个函数都会 return 一个新列表,并且 let 关键字使得无法更改引用的值。那么实现这一目标的功能方法是什么。到目前为止我有这个
let generateCards = {
let ranks = [ 1..52 ]...
}
let shuffle cards = {
}
let cards = shuffle generateCards
洗牌的一种方法是用一系列随机数压缩它,然后按这些数字排序,然后再次解压缩。
let allCards =
[ for rank in 2..14 do
for suit in [Hearts; Diamonds; Spades; Clubs] do
yield { Suit = suit; Rank = rank } ]
let shuffle cards =
let rnd = System.Random()
let rndSequence = Seq.initInfinite (fun _ -> rnd.Next())
Seq.zip cards rndSequence |> Seq.sortBy snd |> Seq.map fst |> Seq.toList
shuffle allCards
上面的内容也可以简化(点头@DaveShaw 的评论),但代价是通过随机生成的键对序列进行排序,使它对人类来说不那么明显:
let shuffle cards =
let rnd = System.Random()
cards |> List.sortBy (fun _ -> rnd.Next())
或更简单(尽管可能对性能影响更大):
let shuffle cards = List.sortBy (fun _ -> System.Guid.NewGuid()) cards
为了最简单,使用无点样式:
let shuffle = List.sortBy (fun _ -> System.Guid.NewGuid())
假设我正在尝试在 f# 中实现某种扑克牌程序。首先是类型系统的正确使用,这里是大量的新手。
type Suit =
| Hearts
| Diamonds
| Spades
| Clubs
type Card = {
Suit:Suit
Rank:int
}
type Hand = {
Cards:List<Card>
}
无论如何,假设我想要一个函数来 return 给我一个可能持有卡片的随机列表。我想我会把两个函数链接在一起,但是我很难在不创建大量对象的情况下实现它们。 list 模块中的每个函数都会 return 一个新列表,并且 let 关键字使得无法更改引用的值。那么实现这一目标的功能方法是什么。到目前为止我有这个
let generateCards = {
let ranks = [ 1..52 ]...
}
let shuffle cards = {
}
let cards = shuffle generateCards
洗牌的一种方法是用一系列随机数压缩它,然后按这些数字排序,然后再次解压缩。
let allCards =
[ for rank in 2..14 do
for suit in [Hearts; Diamonds; Spades; Clubs] do
yield { Suit = suit; Rank = rank } ]
let shuffle cards =
let rnd = System.Random()
let rndSequence = Seq.initInfinite (fun _ -> rnd.Next())
Seq.zip cards rndSequence |> Seq.sortBy snd |> Seq.map fst |> Seq.toList
shuffle allCards
上面的内容也可以简化(点头@DaveShaw 的评论),但代价是通过随机生成的键对序列进行排序,使它对人类来说不那么明显:
let shuffle cards =
let rnd = System.Random()
cards |> List.sortBy (fun _ -> rnd.Next())
或更简单(尽管可能对性能影响更大):
let shuffle cards = List.sortBy (fun _ -> System.Guid.NewGuid()) cards
为了最简单,使用无点样式:
let shuffle = List.sortBy (fun _ -> System.Guid.NewGuid())