Monada stanu
Poświęcimy teraz chwilę na zaimplementowanie trochę bardziej logistycznie skomplikowanej monady, czyli monady stanu. Używamy jej aby propagować stan przez obliczenia.
1:
|
|
Nasze obliczenie otrzyma pewien stan, a następnie zwróci rezultat obliczeń i nowy stan. Ale to wszystko będzie ukryte od programisty, który będzie tylko posługiwał się pewnymi prymitywami.
Zadanie
Napisz funkcje:
stateReturn : 'a -> State<'t, 'a>
, która nie zmieniając stanu zwraca podaną wartośćstateRun : State<'t, 'a> -> 't -> 'a * 't
, która przyjmuje monadę stanu i pewien stan początkowy i zwraca parę (wynik, nowy stan)stateBind : State<'t, 'a> -> ('a -> State<'t, 'b>) -> State<'t, 'b>
stateGet : unit -> State<'t, 't>
to jest w zasadzie wartość monadyczna, która w wyniu ma aktualny stanstatePut : 't -> State<'t, unit>
, która ustawia stan na podanystateModify : ('t -> 't) -> State<'t, unit>
, która modyfikuje stan podaną funkcją
A na koniec utwórz środowisko state { }
, które pozwoli uruchomić poniższy kawałek kodu:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: |
|
Pytania? Jeśli wszystko jasne, to przechodzimy do następnego modułu
Multiple items
union case State.State: ('TState -> 'TResult * 'TState) -> State<'TState,'TResult>
--------------------
type State<'TState,'TResult> = | State of ('TState -> 'TResult * 'TState)
Full name: State_monad.State<_,_>
union case State.State: ('TState -> 'TResult * 'TState) -> State<'TState,'TResult>
--------------------
type State<'TState,'TResult> = | State of ('TState -> 'TResult * 'TState)
Full name: State_monad.State<_,_>
Multiple items
union case Random.Random: int -> Random
--------------------
type Random = | Random of int
Full name: State_monad.Random
union case Random.Random: int -> Random
--------------------
type Random = | Random of int
Full name: State_monad.Random
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val nextRandom : Random -> int * Random
Full name: State_monad.nextRandom
Full name: State_monad.nextRandom
val s : int
val s' : int
namespace System
type Int32 =
struct
member CompareTo : value:obj -> int + 1 overload
member Equals : obj:obj -> bool + 1 overload
member GetHashCode : unit -> int
member GetTypeCode : unit -> TypeCode
member ToString : unit -> string + 3 overloads
static val MaxValue : int
static val MinValue : int
static member Parse : s:string -> int + 3 overloads
static member TryParse : s:string * result:int -> bool + 1 overload
end
Full name: System.Int32
struct
member CompareTo : value:obj -> int + 1 overload
member Equals : obj:obj -> bool + 1 overload
member GetHashCode : unit -> int
member GetTypeCode : unit -> TypeCode
member ToString : unit -> string + 3 overloads
static val MaxValue : int
static val MinValue : int
static member Parse : s:string -> int + 3 overloads
static member TryParse : s:string * result:int -> bool + 1 overload
end
Full name: System.Int32
field int.MaxValue = 2147483647
val stateReturn : x:'a -> State<'b,'a>
Full name: State_monad.stateReturn
Full name: State_monad.stateReturn
val x : 'a
val s : 'b
val stateRun : State<'a,'b> -> s:'a -> 'b * 'a
Full name: State_monad.stateRun
Full name: State_monad.stateRun
val f : ('a -> 'b * 'a)
val s : 'a
val stateBind : m:State<'a,'b> -> f:('b -> State<'a,'c>) -> State<'a,'c>
Full name: State_monad.stateBind
Full name: State_monad.stateBind
val m : State<'a,'b>
val f : ('b -> State<'a,'c>)
val x : 'b
val s' : 'a
val stateGet : unit -> State<'t,'t>
Full name: State_monad.stateGet
Full name: State_monad.stateGet
val s : 't
val statePut : s:'t -> State<'t,unit>
Full name: State_monad.statePut
Full name: State_monad.statePut
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
Full name: Microsoft.FSharp.Core.unit
val stateModify : f:('t -> 't) -> State<'t,unit>
Full name: State_monad.stateModify
Full name: State_monad.stateModify
val f : ('t -> 't)
Multiple items
type StateBuilder =
new : unit -> StateBuilder
member Bind : m:State<'a,'b> * f:('b -> State<'a,'c>) -> State<'a,'c>
member Return : x:'d -> State<'e,'d>
Full name: State_monad.StateBuilder
--------------------
new : unit -> StateBuilder
type StateBuilder =
new : unit -> StateBuilder
member Bind : m:State<'a,'b> * f:('b -> State<'a,'c>) -> State<'a,'c>
member Return : x:'d -> State<'e,'d>
Full name: State_monad.StateBuilder
--------------------
new : unit -> StateBuilder
val this : StateBuilder
member StateBuilder.Return : x:'d -> State<'e,'d>
Full name: State_monad.StateBuilder.Return
Full name: State_monad.StateBuilder.Return
val x : 'd
member StateBuilder.Bind : m:State<'a,'b> * f:('b -> State<'a,'c>) -> State<'a,'c>
Full name: State_monad.StateBuilder.Bind
Full name: State_monad.StateBuilder.Bind
val state : StateBuilder
Full name: State_monad.state
Full name: State_monad.state
type RandomState<'a> = State<Random,'a>
Full name: State_monad.RandomState<_>
Full name: State_monad.RandomState<_>
val nextRandomM : State<Random,int>
Full name: State_monad.nextRandomM
Full name: State_monad.nextRandomM
val r : Random
val x : int
val r' : Random
val randomArrayM : n:int -> State<Random,int list>
Full name: State_monad.randomArrayM
Full name: State_monad.randomArrayM
val n : int
val t : int list
val r : int
val runRandom : seed:Random -> int list
Full name: State_monad.runRandom
Full name: State_monad.runRandom
val seed : Random
val x : int list