Fold

by dimitrs_papadimitriou

HTML

<script src="https://rawgit.com/eu81273/jsfiddle-console/master/console.js"></script>

JavaScript

var algList = {
    evalNode: (l, v, r) => [].concat(l).concat(v).concat(r),
    evalLeaf: (l) => [l]
  };
  
  var algSumInt = {
    evalNode: (l, v, r) => l + v + r,
    evalLeaf: (l) => l
  };
  
  var algPr = {
    evalNode: (l, v, r) => `((${l}),${v},(${r}))`,
    evalLeaf: (l) => l
  };
  
  var sumVsitor =  ( s)=>
  ({  
     visitNode : ( n) => {   
      s.v =s.v + n.v; 
      console.log(`sum; ${  s.v } - Node  ${n.cata(algPr)}`);    
      n.l.accept(  sumVsitor( s) );
      n.r.accept(  sumVsitor( s));  
    },  
  
    visitLeaf:l => {
      console.log(`sum; ${  s.v } - Leaf  ${l.cata(algPr)}`);
      s.v =s.v + l.v 
    }
  });
  
  
  var n = (l, v, r) => ({
    l: l,
    v: v,
    r: r,
    map: f => n(l.map(f), f(v), r.map(f)),
    cata: (alg) => alg.evalNode(l.cata(alg), v, r.cata(alg)),
    accept: ( visitor) => { visitor.visitNode( n(l, v, r)) }
   
  });
  
  var lf = v => ({
    v: v, 
    map: f => lf(f(v)),
    cata: (alg) => alg.evalLeaf(v),
    accept: ( visitor) => { visitor.visitLeaf( lf(v)) }
  });
  
  var inst = n(lf(2), 2, lf(3));
  
  var inst = n(n(n(lf(2), 2, lf(3)), 2, lf(3)), 2, n(lf(2), 2, n(lf(2), 2, lf(3))));
  
   console.log(inst.cata(algPr));
  //console.log(inst.eval(algList));
  
  var s = { v:0};
   inst.accept( sumVsitor( s ))
  console.log(s );
  
  
  const some = v => ({
    v: v,
    map: f => some(f(v)),
    bind: f => f(v),
    apply: value => v(value),
    app: f => f.map(g => g(v)), 
   });
  
  var none = v => ({
    map: f => none(),
    fold: (acc, accf) => acc,
    apply: value => none(),
    app: f => none()
  });