# Objective

Generate a Tic-Tac-Toe grid and provide a function to identify if all rows match a particular pattern.

- First let’s generate a Tic-Tac-Toe grid:let grid = [ for i in 0..8 -> (i, true) ] |> Map.ofSeqSo what’s happening here?

- We declare a value called grid that by default is immutable:
- let grid = …
- We then need to generate the actual grid structure.for i in 0..8 -> (i, true) ]
- To do this, we can generate a tuple<int, bool> nine times.

The keyword “for” is used to create a for-loop construct.

As a result, we can perform some arbitrary operation a variable number of times.

Now you might ask, so what’s the variable?

We declare the elements within our collection here:

0..8

This is shorthand for the following:

{0;1;2;3;4;5;6;7;8;}

The 0..8 syntax tells the runtime to create a set of 9 elements from 0 to 8 for our grid.

When using this shorthand within a for-loop construct, we can omit the sequence notation “{}”.

However, my brain feels better by being explicit with the sequence notation “{0..8}”.

[ for i in {0..8} -> (i, true) ]

This “->” symbol can be thought of as a yield operator.

So whenever we want to generate a value, we can use the yield operator (“->”) followed by an expression to generate a value or a set of values.

- We then place this expression within brackets.Therefore the expression, “[ for i in {0..8} -> (i, true) ]”, will generate a list of nine elements.
- When we place data inside brackets then we are really expressing a list of data.
- Now let’s validate that all rows share a common value.

rows |> Seq.forall (fun row ->

row |> Seq.forall (fun kvp -> kvp.Value)) |> should equal true

When programming in F#, we have to remember that by default, there are no objects. Instead, the default consists of two things:

- Structures
- Functions

Based on these fundamentals, we cannot view F# as arbitrary objects relying on their own methods to process data.

Instead we need to swap this paradigm:

Try to view F# as arbitrary functions that operate on values (primitive or collections) to generate results.

Again, do not try to read lines of F# as if you’re reading C# code.

Instead, read F# like a set of stages from left to right where “|>” can be read as a “pipeline”:

Data3 = data1 |> function1() -> data2 |> function2() -> ↓

↑ ← ← ← ← ← ← ← ← ← ← ←← ← ← ←← ← ← ←←