Lets say i am attempting to implement some sort of poker program in f#. Firstly is this the correct use of the type system, massive newbie here.
type Suit =
| Hearts
| Diamonds
| Spades
| Clubs
type Card = {
Suit:Suit
Rank:int
}
type Hand = {
Cards:List<Card>
}
Anyway suppose i want a function to return me a randomised list of the possible holding cards. I guess there would be two functions which i would chain together, however i am having a hard time implementing them without creating a loads of objects. each of the functions in the list module will return a new list and the let keyword makes impossible to change value of the reference. what is the functional way of achieving this then. So far i have this
let generateCards = {
let ranks = [ 1..52 ]...
}
let shuffle cards = {
}
let cards = shuffle generateCards
One way to shuffle a deck would be to zip it with a sequence of random numbers, then sort by those numbers, then unzip again.
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
The above could also be simplified (nod to @DaveShaw's comment), though at a cost of making it less obvious to a human, by sorting the sequence by a randomly generated key:
let shuffle cards =
let rnd = System.Random()
cards |> List.sortBy (fun _ -> rnd.Next())
Or even simpler (though, possibly, with more performance impact):
let shuffle cards = List.sortBy (fun _ -> System.Guid.NewGuid()) cards
And for ultimate simplicity, go point-free style:
let shuffle = List.sortBy (fun _ -> System.Guid.NewGuid())