ExpandCollapseNext Index

+ 1.1 monad-01.flx

  //Check typeclasses:monad
  
  typedef fun Maybe (t:TYPE):TYPE=>opt[t];
  
  instance Monad [Maybe] {
    fun bind[a,b] (x:Maybe a, f:a -> Maybe b) =>
      match x with
      | #None[a] => None[b]
      | Some x => f x
      endmatch
    ;
  
    fun ret[a](x:a):Maybe a => Some x;
  }
  
  fun madd(x:double) (y:double):opt[double]=>Some (y + x);
  fun msub(x:double) (y:double):opt[double]=>Some (y - x);
  fun mmul(x:double) (y:double):opt[double]=>Some (y * x);
  fun mdiv(x:double) (y:double):opt[double]=>
    if x == 0.0 then None[double] else Some (y/x) endif
  ;
  fun mneg(x:double):opt[double]=>Some (-x);
  
  open Monad[Maybe];
  
  proc show(r:Maybe double) {
     match r with
    | Some x => { print x; }
    | #None => { print "divide by zero somewhere"; }
    endmatch; endl;
  }
  
  // we have to put this here so it overrides left shift assignment operator
  
  syntax monad {
    x[ssetunion_pri] := x[ssetunion_pri] ">>=" x[>ssetunion_pri] =># "`(ast_apply ,_sr (bind (,_1 ,_3)))";
  }
  open syntax monad;
  
  var x1 = 2.7; var y1 = 1.2; var z = 0.0;
  {
    var r = ret x1 >>= msub y1 >>= mdiv z;
    show r;
  };
  
  {
    var r = ret x1 >>= msub y1 >>= mdiv 2.0;
    show r;
  };
  

divide by zero somewhere
0.75