Another tennis implementation

Simple game of tennis... refactored after reading Richard Minerich blog post @http://richardminerich.com/2011/02/the-road-to-functional-programming-in-f-from-imperative-to-computation-expressions/

Copy Source
Copy Link
Tools:
 1: // This file is a script that can be executed with the F# Interactive.  
 2: // It can be used to explore and test the library project.
 3: // Note that script files will not be part of the project build.
 4: 
 5: type Player = A | B
 6: 
 7: type Score = 
 8:     | Love
 9:     | Five
10:     | Thirty
11:     | Forty
12: 
13: type GameState = 
14:     | InPlay of Score * Score
15:     | Duece
16:     | Advantage of Player
17:     | Won of string
18: 
19: type GameFunc = (GameState -> GameState)
20: 
21: let delay f = f()
22: 
23: let start = InPlay(Love,Love)
24: 
25: let play player state =
26:      let nextScore score =
27:          match score with
28:          | Love -> Five
29:          | Five -> Thirty
30:          | Thirty -> Forty
31:          | Forty -> Forty
32: 
33:      match state with
34:      | InPlay(p1,p2) -> 
35:           match player with 
36:           | _ when (p1 = Thirty && p2 = Forty) || (p1 = Forty && p2 = Thirty) -> Duece
37:           | A when p1 = Forty -> Won("Player 1")
38:           | B when p2 = Forty -> Won("Player 2")
39:           | A -> InPlay(nextScore p1, p2)
40:           | B -> InPlay(p1, nextScore p2)
41:      | Duece -> Advantage(player)
42:      | Advantage(p) when p = player ->  Won("Player 1")
43:      | Advantage(_) -> Duece  
44:      | _ -> state
45: 
46: type GameBuilder() =
47:     member b.Zero() = (fun _ -> start)
48:     member b.Yield(a : GameFunc) = a
49:     member b.Combine(a : GameFunc, b' : GameFunc) = a >> b'
50:     member b.For(vals : seq<Player>, f : Player -> GameFunc) = 
51:          vals |> Seq.fold (fun s n -> b.Combine(s, f n)) (b.Zero())
52:  
53:     static member Start (state : GameState) (func : GameFunc) = 
54:         func(state)
55:     
56: let game = GameBuilder()
57: 
58: let playerThatWins = [A;B;A;B;A;B;B;A;A;A] |> Seq.ofList
59: 
60: let result = game {
61:                     for playerwin in playerThatWins do 
62:                         yield play playerwin 
63:              } |> GameBuilder.Start start
union case Player.A: Player
union case Player.B: Player
type Score =
  | Love
  | Five
  | Thirty
  | Forty

Full name: Snippet.Score

  type: Score
  implements: System.IEquatable<Score>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Score>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
union case Score.Love: Score
union case Score.Five: Score
union case Score.Thirty: Score
union case Score.Forty: Score
type GameState =
  | InPlay of Score * Score
  | Duece
  | Advantage of Player
  | Won of string

Full name: Snippet.GameState

  type: GameState
  implements: System.IEquatable<GameState>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<GameState>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
union case GameState.InPlay: Score * Score -> GameState
union case GameState.Duece: GameState
union case GameState.Advantage: Player -> GameState
type Player =
  | A
  | B

Full name: Snippet.Player

  type: Player
  implements: System.IEquatable<Player>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Player>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
union case GameState.Won: string -> GameState
Multiple items
val string : 'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------

type string = System.String

Full name: Microsoft.FSharp.Core.string

  type: string
  implements: System.IComparable
  implements: System.ICloneable
  implements: System.IConvertible
  implements: System.IComparable<string>
  implements: seq<char>
  implements: System.Collections.IEnumerable
  implements: System.IEquatable<string>
type GameFunc = GameState -> GameState

Full name: Snippet.GameFunc
val delay : (unit -> 'a) -> 'a

Full name: Snippet.delay
val f : (unit -> 'a)
val start : GameState

Full name: Snippet.start

  type: GameState
  implements: System.IEquatable<GameState>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<GameState>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
val play : Player -> GameState -> GameState

Full name: Snippet.play
val player : Player

  type: Player
  implements: System.IEquatable<Player>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Player>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
val state : GameState

  type: GameState
  implements: System.IEquatable<GameState>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<GameState>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
val nextScore : (Score -> Score)
val score : Score

  type: Score
  implements: System.IEquatable<Score>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Score>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
val p1 : Score

  type: Score
  implements: System.IEquatable<Score>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Score>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
val p2 : Score

  type: Score
  implements: System.IEquatable<Score>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Score>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
val p : Player

  type: Player
  implements: System.IEquatable<Player>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Player>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
type GameBuilder =
  class
    new : unit -> GameBuilder
    member Combine : a:GameFunc * b':GameFunc -> (GameState -> GameState)
    member For : vals:seq<Player> * f:(Player -> GameFunc) -> (GameState -> GameState)
    member Yield : a:GameFunc -> GameFunc
    member Zero : unit -> ('a -> GameState)
    static member Start : state:GameState -> func:GameFunc -> GameState
  end

Full name: Snippet.GameBuilder
val b : GameBuilder
member GameBuilder.Zero : unit -> ('a -> GameState)

Full name: Snippet.GameBuilder.Zero
member GameBuilder.Yield : a:GameFunc -> GameFunc

Full name: Snippet.GameBuilder.Yield
val a : GameFunc
member GameBuilder.Combine : a:GameFunc * b':GameFunc -> (GameState -> GameState)

Full name: Snippet.GameBuilder.Combine
val b' : GameFunc
member GameBuilder.For : vals:seq<Player> * f:(Player -> GameFunc) -> (GameState -> GameState)

Full name: Snippet.GameBuilder.For
val vals : seq<Player>

  type: seq<Player>
  inherits: System.Collections.IEnumerable
Multiple items
val seq : seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------

type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>

  type: seq<'T>
  inherits: System.Collections.IEnumerable
val f : (Player -> GameFunc)
module Seq

from Microsoft.FSharp.Collections
val fold : ('State -> 'T -> 'State) -> 'State -> seq<'T> -> 'State

Full name: Microsoft.FSharp.Collections.Seq.fold
val s : (GameState -> GameState)
val n : Player

  type: Player
  implements: System.IEquatable<Player>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Player>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
member GameBuilder.Combine : a:GameFunc * b':GameFunc -> (GameState -> GameState)
member GameBuilder.Zero : unit -> ('a -> GameState)
static member GameBuilder.Start : state:GameState -> func:GameFunc -> GameState

Full name: Snippet.GameBuilder.Start
val func : GameFunc
val game : GameBuilder

Full name: Snippet.game
val playerThatWins : seq<Player>

Full name: Snippet.playerThatWins

  type: seq<Player>
  inherits: System.Collections.IEnumerable
val ofList : 'T list -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.ofList
val result : GameState

Full name: Snippet.result

  type: GameState
  implements: System.IEquatable<GameState>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<GameState>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
val playerwin : Player

  type: Player
  implements: System.IEquatable<Player>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Player>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
static member GameBuilder.Start : state:GameState -> func:GameFunc -> GameState

More information

Link: http://fssnip.net/8Q
Posted: 3 months ago
Author: Colin Bull
Tags: tennis, computational workflows