Advertisement
mary-perret-1986

Untitled

Mar 18th, 2021
2,221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 2.17 KB | None | 0 0
  1. module State =
  2.     let inline run state x = let (State(f)) = x in f state
  3.     let get = State(fun s -> s, s)
  4.     let put newState = State(fun _ -> (), newState)
  5.     let map f s = State(fun (state: 's) ->
  6.        let x, state = run state s
  7.        f x, state)
  8.  
  9. /// The state monad passes around an explicit internal state that can be
  10. /// updated along the way. It enables the appearance of mutability in a purely
  11. /// functional context by hiding away the state when used with its proper operators
  12. /// (in StateBuilder()). In other words, you implicitly pass around an implicit
  13. /// state that gets transformed along its journey through pipelined code.
  14. type StateBuilder() =
  15.    member this.Zero () = State(fun s -> (), s)
  16.    member this.Return x = State(fun s -> x, s)
  17.    member inline this.ReturnFrom (x: State<'s, 'a>) = x
  18.    member this.Bind (x, f) : State<'s, 'b> =
  19.        State(fun state ->
  20.            let (result: 'a), state = State.run state x
  21.             State.run state (f result))
  22.     member this.Combine (x1: State<'s, 'a>, x2: State<'s, 'b>) =
  23.         State(fun state ->
  24.             let _, state = State.run state x1
  25.             State.run state x2)
  26.     member this.Delay f : State<'s, 'a> = f ()
  27.     member this.For (seq, (f: 'a -> State<'s, 'b>)) =
  28.        seq
  29.        |> Seq.map f
  30.        |> Seq.reduceBack (fun x1 x2 -> this.Combine (x1, x2))
  31.    member this.While (f, x) =
  32.        if f () then this.Combine (x, this.While (f, x))
  33.        else this.Zero ()
  34.  
  35. let state = StateBuilder()
  36.  
  37. let rec playGame =
  38.    function
  39.    | []-> state {
  40.            let! (_, score) = State.get
  41.            return score
  42.        }
  43.    | x::xs-> state {
  44.            let! (on, score) = State.get
  45.            match x with
  46.            | 'a' when on -> do! State.put (on, score + 1)
  47.            | 'b' when on -> do! State.put (on, score - 1)
  48.            | 'c'         -> do! State.put (not on, score)
  49.            | _           -> do! State.put (on, score)
  50.            return! playGame xs
  51.        }
  52.  
  53. [<EntryPoint>]
  54. let main _ =
  55.    let startState = (false, 0)
  56.    let moves = toList "abcaaacbbcabbab"
  57.    State.eval (playGame moves) startState
  58.    |> printfn "%A"
  59.    0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement