I skipped the rest of the algorithm – it’s identical to previous implementations. Now we can write unit tests for our multi-dimensional implementation that will verify behavior for both 2D and 3D boards:
[<Test>] member this.``Square in 3d should not change``() = let pattern = [Space(1,1,0); Space(1,2,0); Space(2,1,0); Space(2,2,0)] pattern |> nextGeneration |> should equal pattern [<Test>] member this.``Cube in 3d should die``() = let pattern = [Space(1,1,1); Space(1,2,1); Space(2,1,1); Space(2,2,1); Space(1,1,2);Space(1,2,2) Space(2,1,2); Space(2,2,2)] pattern |> nextGeneration |> should equal List.empty
But wait – we don’t need to restrict us to geometrical distances between cells. We can implement Conway’s Game of Life for colors! We just need to throw a definition of neigbouring colors:
type Color = Red | Green | Blue | White | Gray | Black | Orange | Yellow | Brown let neighbours color = match color with | Red -> [Red;Orange;Brown] | Green -> [Green;Blue;Yellow] | Blue -> [Blue;Green] | White -> [White;Gray] | Black -> [Black;Gray] | Gray -> [Gray;Black;White] | Orange -> [Orange;Red;Yellow] | Yellow -> [Yellow;Orange;Green] | Brown -> [Brown;Red]
Again, the remaining part of the algorithm is a verbatim copy of our original definition, so I skipped that. To test the implementation, we’ll define a test pattern: let pattern = [Red;Green;Orange;Black]
… and execute the “nextGeneration” function: nextGeneration pattern
Here’s the result of the execution: val it : Color list = [Red; Orange]
While you have support for generics in C#, you don’t have the same implementation transparency due to lack of type interference. Specialized implementations in C# are more straightforward (and smaller in size) than generic ones, so developers usually begin with specialized algorithms and data structures and only convert them to generic implementations once they have needs for that. In F# it’s opposite: the functions are initially generic with type constraints applied only where they refer to functions with arguments or return values of specific types. And as we saw in examples above, such language capability leads to very high level of code reuse, including applicability to data types that we haven’t originally thought of.
Vagif Abilov is a Russian/Norwegian software developer and architect working for Miles. He has more than twenty years of programming experience that includes various programming languages, currently using mostly C# and F#. Vagif writes articles and speaks at user group sessions and conferences. He is a contributor to several open source projects and maintainer of a few ones, such as Simple.Data OData adapter, Simple.OData.Client and MongOData.
Software Development Oslo, Kjeller, Stavanger, Bergen
Schlumberger is a knowledge based company in the energy sector, with world class centers for Software Development located here in Norway. We have offices in Oslo, Kjeller, Bergen and Stavanger, responsible for delivering market leading software platforms for the oil-and gas industry. With more than 200 software engineers, we are a leading employer and competency center for software development in Norway. Our activities cover a wide range of activities, from software architecture, design, engineering to customer support, from technical documentation to quality assurance. We take great pride in our internationally diverse environment and our ability to consistently build innovative and integrated products with high quality. Schlumberger closely collaborates with Universities and Research Centers in Norway and throughout the rest of the world. All employees benefit from tailored and continuous training programs, state-of-the-art communication technologies and a global organization that supports knowledge sharing and team work. We encourage patent applications, conference participation and journal publications. For job opportunities, please contact firstname.lastname@example.org