Skip to content

Instantly share code, notes, and snippets.

@akimboyko
Created January 12, 2014 13:24
Show Gist options
  • Save akimboyko/8384563 to your computer and use it in GitHub Desktop.
Save akimboyko/8384563 to your computer and use it in GitHub Desktop.
DI patterns from Scala adopted to F#: structural typing and currying
// 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