Here is a way to use a list of mutable (ref-cells) tickets:
let maxSeats = 10
let tickets : (int * Ticket option) ref list =
[1..maxSeats]
|> List.map (fun s -> ref (s, None) )
let bookSeat seat name =
match List.tryFind (fun r -> let (s,_) = !r in s = seat) tickets with
| Some r ->
r :=
match !r with
| (s, Some ticket) -> (s, Some { ticket with customer = name })
| (s, None) -> (s, Some { seat = s; customer = name })
| None ->
failwith "seat not found"
obvious you can make tickets
itself mutable too, if you want to add
seats instead of initializing them with all the obvious seats
a better approach(?)
Still I think that this is the wrong way to do it - I think you want a Map:
type Ticket = {seat:int; customer:string}
type Tickets = Map<int, Ticket>
let bookSeat seat name (tickets : Tickets) =
match Map.tryFind seat tickets with
| Some oldTicket ->
tickets
|> Map.remove seat
|> Map.add seat { oldTicket with customer = name }
| None ->
tickets
|> Map.add seat { seat = seat; customer = name }
note that these are all immutable values, so bookSeat
will return a new Ticket
-reservation-map
hyprid using Dictionary
or you can use a common .net Dictionary
and mutate this:
type Ticket = {seat:int; customer:string}
let tickets = System.Collections.Generic.Dictionary<int, Ticket>()
let bookSeat seat name =
match tickets.TryGetValue seat with
| (true, oldTicket) ->
tickets.[seat] <- { oldTicket with customer = name }
| (false, _) ->
tickets.[seat] <- { seat = seat; customer = name }
Here you don't have to pass the Tickets
around - they will be mutated in place (but still the Ticket
-objects themselves are still immutable)
Note that this right now is not thread-safe so be careful.