F # how to add type to list?

So I am trying to create a card game for a school project with F #. I am coming from C # and have trouble understanding things in F #. I have a type

Player = {Name : String; Hand : Card list}

that represents the player

then I have a deck that has cards inside. How to transfer the first card from the deck to the players hand? In C #, I would use something like removeat[i]

.

+3


source to share


3 answers


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

      

Pass your list and it will return a tuple. The first value will be your card, the second will be the rest of the deck. Using Some and None there is like running out of cards in the deck, then you won't get a card back. As you from a C # background think of as a nullable Some

type and None

as null. Take a look at F # Some

and None

if you're not sure what are the most common uses for them.

You can use this like



 let (topCard, restOfDeck) = returnFirstElement deckOfCards

      

May be of extra help if needed, but this should be a good enough start.

+6


source


To write idiomatic functional code in F #, you need to think about how to explicitly model system state. Each player has a hand of cards that represent part of the state, but we also need to simulate the state of the deck.

Logically, drawing from a deck affects both the player's hand and the deck.

We also need to consider the error case where there are no cards in the deck.

Here's a simple example: just mistakes when there are no cards in the deck.



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)

      

You also pass the Player

deck represented by the function Card list

to the draw function, and it returns you a new one Player

with the card taken from the deck and a new one Card list

without the card that was drawn.

For some games, you might be better off having two lists of cards, one drawable, one trash. Then, when you run out of cards, you can create a new deck by shuffling the throws.

+2


source


You can of course use anything .Net in F #. It's not idiomatic F #, but again, it's a moot point about how much recursion is. Basically, if you want to remove an item from an F # list, the F # list might not be the best collection to use. You can of course apply filter

to it at any time. But if all of your items are unique, consider using a set.

Here's the version with .RemoveAt:

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

xs

      

ResizeArray is a synonym for C # list.

Relatively simple movement of the first card and the rest you can use the "tail" and "head" functions.

0


source







All Articles