How do I iterate over a list of union cases and access each case's data?
I have this line:
root.Neighbors |> Seq.filter(fun x -> print x)
However, Neighbors is a list:
Neighbors=[ One { State=Survives; Neighbors=[] }
Two { State=Survives; Neighbors=[] }
Three { State=Survives; Neighbors=[] }
Four { State=Survives; Neighbors=[] }
Six { State=Survives; Neighbors=[] }
Seven { State=Survives; Neighbors=[] }
Eight { State=Survives; Neighbors=[] }
Nine { State=Survives; Neighbors=[] } ]
I need to access the state of each neighbor within the list of neighbors.
However, I receive the following error:
The type 'Neighbor' does not match the type 'Cell' Type mismatch. Expecting a Neighbor -> unit but given a Cell -> unit
NOTE: Do I really need to do pattern matching just to access all of the neighbors?
Code:
module GameOfLife
type Neighbor = | One of Cell
| Two of Cell
| Three of Cell
| Four of Cell
| Six of Cell
| Seven of Cell
| Eight of Cell
| Nine of Cell
and CauseOfDeath = | Underpopulated // Fewer than 2 live neighbors
| Overpopulated // More than 3 live neighbors
and State = | Dies of CauseOfDeath
| Survives // 2 or 3 live neighbors
| Resurected // Is dead and has 3 live neighbors
and Neighbors = Neighbor List
and Cell = { State:State; Neighbors:Neighbors }
let letThereBeLife() =
{ State=Survives; Neighbors=[ One { State=Survives; Neighbors=[] }
Two { State=Survives; Neighbors=[] }
Three { State=Survives; Neighbors=[] }
Four { State=Survives; Neighbors=[] }
Six { State=Survives; Neighbors=[] }
Seven { State=Survives; Neighbors=[] }
Eight { State=Survives; Neighbors=[] }
Nine { State=Survives; Neighbors=[] } ] }
let print (cell:Cell) =
printf "This cell %A\n%A" cell.State cell.Neighbors
let tick root =
root.Neighbors |> Seq.iter(print)
When you have a complex disriminated union with cases that share some common state between the cases, and you want to hide it behind a simpler interface, one technique would be to have a member that would hide the pattern matching boilerplate.
type Neighbor =
| One of Cell
...
| Nine of Cell
static member Cell (n: Neighbor) =
match n with
| One cell
...
| Nine cell -> cell
root.Neighbors |> Seq.iter (Neighbor.Cell >> print)
As others mentioned in the comments however, you should really rethink your design. This huge Neighbor type feels like you discriminate over a wrong dimension.