3 people like it.

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/

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
// This file is a script that can be executed with the F# Interactive.  
// It can be used to explore and test the library project.
// Note that script files will not be part of the project build.

type Score = 
    | Love
    | Five
    | Thirty
    | Forty
    | Adv
    | Win
    with 
        member x.Won() = 
            match x with
            | Love -> Five
            | Five -> Thirty
            | Thirty -> Forty
            | Forty -> Win
            | Adv -> Win
            | Win -> Win
        member x.Lost() =
            match x with
            | Adv -> Forty
            | _ -> x

type Player = A | B

type GameState =
    | InPlay of Score * Score
    | Won of string
           

let succeed x = x
let fail = None
let bind p rest =
    printfn "%A" p
    match p with
    | InPlay(Score.Win, _) -> Won("Player 1")
    | InPlay(_, Score.Win) -> Won("Player 2")
    | _ -> rest p

let delay f = f()

type GameBuilder() =
    member b.Return(x)  = succeed x
    member b.Bind(p, rest) = bind p rest
    member b.Delay(f)   = delay f
    member b.Let(p,rest) : GameState = rest p

let game = GameBuilder()


let play player state =
     match state with
     | InPlay(p1,p2) -> 
           match player with
           | A when p1 = Forty && p2 = Forty -> InPlay(Adv, p2.Lost())
           | B when p2 = Forty && p2 = Forty -> InPlay(p1.Lost(), Adv) 
           | A -> InPlay(p1.Won(), p2.Lost())
           | B -> InPlay(p1.Lost(), p2.Won())
     | _ -> state

let start = InPlay(Love,Love)

let result = game { 
                    let! a = play A start
                    let! b = play B a
                    let! c = play A b
                    let! d = play B c
                    let! e = play A d
                    let! f = play B e
                    let! g = play A f
                    let! h = play B g
                    let! i = play B h
                    return i
                 }
union case Score.Love: Score
union case Score.Five: Score
union case Score.Thirty: Score
union case Score.Forty: Score
union case Score.Adv: Score
union case Score.Win: Score
val x : Score
member Score.Won : unit -> Score

Full name: Script.Score.Won
member Score.Lost : unit -> Score

Full name: Script.Score.Lost
type Player =
  | A
  | B

Full name: Script.Player
union case Player.A: Player
union case Player.B: Player
type GameState =
  | InPlay of Score * Score
  | Won of string

Full name: Script.GameState
union case GameState.InPlay: Score * Score -> GameState
type Score =
  | Love
  | Five
  | Thirty
  | Forty
  | Adv
  | Win
  member Lost : unit -> Score
  member Won : unit -> Score

Full name: Script.Score
union case GameState.Won: string -> GameState
Multiple items
val string : value:'T -> string

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

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val succeed : x:'a -> 'a

Full name: Script.succeed
val x : 'a
val fail : 'a option

Full name: Script.fail
union case Option.None: Option<'T>
val bind : p:GameState -> rest:(GameState -> GameState) -> GameState

Full name: Script.bind
val p : GameState
val rest : (GameState -> GameState)
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val delay : f:(unit -> 'a) -> 'a

Full name: Script.delay
val f : (unit -> 'a)
Multiple items
type GameBuilder =
  new : unit -> GameBuilder
  member Bind : p:GameState * rest:(GameState -> GameState) -> GameState
  member Delay : f:(unit -> 'b) -> 'b
  member Let : p:'a * rest:('a -> GameState) -> GameState
  member Return : x:'c -> 'c

Full name: Script.GameBuilder

--------------------
new : unit -> GameBuilder
val b : GameBuilder
member GameBuilder.Return : x:'c -> 'c

Full name: Script.GameBuilder.Return
val x : 'c
member GameBuilder.Bind : p:GameState * rest:(GameState -> GameState) -> GameState

Full name: Script.GameBuilder.Bind
member GameBuilder.Delay : f:(unit -> 'b) -> 'b

Full name: Script.GameBuilder.Delay
val f : (unit -> 'b)
member GameBuilder.Let : p:'a * rest:('a -> GameState) -> GameState

Full name: Script.GameBuilder.Let
val p : 'a
val rest : ('a -> GameState)
val game : GameBuilder

Full name: Script.game
val play : player:Player -> state:GameState -> GameState

Full name: Script.play
val player : Player
val state : GameState
val p1 : Score
val p2 : Score
member Score.Lost : unit -> Score
member Score.Won : unit -> Score
val start : GameState

Full name: Script.start
val result : GameState

Full name: Script.result
val a : GameState
val b : GameState
val c : GameState
val d : GameState
val e : GameState
val f : GameState
val g : GameState
val h : GameState
val i : GameState

More information

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