Created
January 12, 2014 13:24
-
-
Save akimboyko/8384563 to your computer and use it in GitHub Desktop.
DI patterns from Scala adopted to F#: structural typing and currying
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Inspired by Scala and http://skov-boisen.dk/?p=289 | |
type Cell() = | |
override m.ToString() = "*" | |
type IGameOfLife = | |
abstract member Next: IGameOfLife | |
abstract member Generation : seq<Cell> | |
// Types for Structural Typing | |
// one types hierarhy | |
type Generator() = | |
member x.Generate: seq<Cell> = | |
seq([new Cell(); new Cell(); new Cell()]) | |
// another types hierarhy | |
type ParametrizedGenerator(cellsDencity: float32, numberOfCells: int) = | |
member x.Generate: seq<Cell> = | |
[1 .. numberOfCells] | |
|> Seq.map(fun x -> new Cell()) | |
// only requred to have method Generate. not to be in same type heirarhy | |
let inline initStructuralTypingGameOfLife< ^R when ^R : (member Generate : seq<Cell>)> (rules: ^R)= | |
let cells = (^R : (member Generate : seq<Cell>) rules) | |
{ | |
new IGameOfLife with | |
member this.Next = | |
// create next game instance/generation | |
this // this is only simplification | |
member x.Generation: seq<Cell> = cells | |
} | |
// Simplify DI using partial application and currying | |
// for DI using function currying | |
type GameOfLife(numberOfCells: int, rules: int -> ParametrizedGenerator) = | |
let cells = rules(numberOfCells).Generate | |
interface IGameOfLife with | |
member this.Next = | |
// create next game instance/generation | |
this :> IGameOfLife // this is only simplification | |
member x.Generation : seq<Cell> = cells | |
// function to be simplified | |
let gameOfLifeDefinition cellsDencity numberOfCells = | |
new ParametrizedGenerator(cellsDencity, numberOfCells) | |
// Sample code | |
[<EntryPoint>] | |
let main argv = | |
let rules = new Generator() | |
let anonymousRules = new ParametrizedGenerator(0.5f, 4) | |
let structuralTypingSample = initStructuralTypingGameOfLife(rules) | |
let anotherStructuralTypingSample = initStructuralTypingGameOfLife(anonymousRules) | |
printfn "Case #1: %A" structuralTypingSample.Generation | |
printfn "Case #2: %A" anotherStructuralTypingSample.Generation | |
let generalGameOfLifeDefinition = gameOfLifeDefinition 0.75f | |
let functionCurryingSample = new GameOfLife(10, generalGameOfLifeDefinition) :> IGameOfLife | |
printfn "Case #3: %A" functionCurryingSample.Generation | |
0 // return an integer exit code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment