I am a C# developer learning F#. Would appreciate any suggestions on how this code can be improved. Main points I am interested in:
- Functional style of the code, absense of imperative style(C#) artifacts
- F# collection data types and functions usage
- General code(not algorithm) efficiency
Code style, naming etc.
let life board = let flatten = Seq.cast<int> >> Seq.toArray let neighboursCount (board: int[,]) x y = board.[y..y+2, x..x+2] |> flatten |> Array.mapi (fun i el -> (i <> 4, el)) |> Array.filter fst |> Array.map snd |> Array.filter ((=) 1) |> Array.length let expandBoard board = let N = Array2D.length1 board array2D [| yield [| yield board.[N - 1, N - 1]; yield! board.[N - 1, *]; yield board.[N - 1, 0] |] for i in [0..N - 1] do yield [| yield board.[i, N - 1]; yield! board.[i, *]; yield board.[i, 0] |] yield [| yield board.[0, N - 1]; yield! board.[0, *]; yield board.[N - 1, 0] |] |] let getNextBoard board = let eBoard = expandBoard board board |> Array2D.mapi (fun i j elem -> match neighboursCount eBoard j i with | 2 -> elem | 3 -> 1 | _ -> 0) let isGameOver board prevBoards = board |> flatten |> Array.forall ((=) 0) || List.contains board prevBoards let rec lifeRec board prevBoards = printfn "%A \n" board if isGameOver board prevBoards then () else getNextBoard board |> lifeRec <| board::prevBoards lifeRec board  let N = 5 let rnd = System.Random() Array2D.init N N (fun _ _ -> rnd.Next 2) |> life