ExpandCollapsePrev Next Index

+ 2.1 monad-02.flx

  //git://github.com/shayne-fletcher/zen.git
  
  //State monad.
  
  union state[s, a] =
   | State of (s->a*s)
   ;
  
  fun run_state[s, a] (x:state[s, a]):(s->a*s) =>
   match x with
     | State u => u
   endmatch
    ;
  
  typedef fun StateGen (s:TYPE) (a:TYPE) : TYPE => state[s, a] ;
  
  instance[s] Monad[StateGen s]
  {
   fun bind[a,b](x:StateGen s  a, f:a->StateGen s b):StateGen s  b =
   {
     val run0:(s->a*s) = run_state x ;
     fun run1 (state0:s):(b*s) =
     {
       val t:a*s = run0 state0 ;
       return (run_state (f t.0)) t.1;
     }
  
     return State run1 ;
   }
  
   fun ret[a](x:a):StateGen s a =
   {
     return State (fun (st:s):a*s => (x, st)) ;
   }
  }
  
  //--
  //
  //Test.
  
  struct counter
  {
   value : int ;
   number_of_increments : int ;
  };
  
  instance Str[counter]
  {
   fun str (c:counter):string =>
     "Counter (value = " + str (c.value) +
     ", number_of_increments = " + str (c.number_of_increments) + ")"
     ;
  }
  
  fun increment_counter (c:counter):(int*counter) =>
   (c.value, counter (c.value+1, c.number_of_increments+1))
   ;
  
  val increment_counter_state : state[counter, int] = State increment_counter ;
  println $ str ((run_state increment_counter_state) (counter (24, 3))) ;
  
  //So far so good.
  
  open Monad[StateGen counter] ;
  
  val increment_counter_twice_state =
   bind (increment_counter_state, (fun (x:int):state[counter,int] => increment_counter_state)) ;
  
  // // syntax monad //Override the right shift assignment operator.
  // // {
  // //   x[ssetunion_pri] := x[ssetunion_pri] ">>=" x[>ssetunion_pri] =># "`(ast_apply ,_sr (bind (,_1 ,_3)))";
  // // }
  // // open syntax monad;
  
  // // val g = increment_counter_state >>= (fun (x:int):state[counter,int] => increment_counter_state) ;
  
  

(24, Counter (value = 25, number_of_increments = 4))