JSFiddle - React, Tailwind, and code Playground

by dimitrs_papadimitriou

JavaScript

class Continuation {
  constructor(x) {
    this.x = x;
  }
}

Continuation.prototype.of = Continuation.of = x => {
  return new Continuation(resolve => resolve(x));
};

Continuation.prototype.chain = function(f) {
  const x = this.x;
  return new Continuation(resolve => {
    x(res => f(res).x(res2 => resolve(res2)));
  });
};

Continuation.prototype.run = function(f) {
  return this.x(f);
};

Continuation.prototype.inspect = function() {
  return `Continuation(${this.x})`;
};

// derivations
Continuation.prototype.map = function(f) {
  var m = this;
  return m.chain(a => m.of(f(a)));
};

Continuation.prototype.app = function(m) {
  return this.chain(f => m.map(f));
};
Continuation.prototype.then = function(alg) {
  return this.x(alg);
};

var n = (l, v, r) => ({
  l: l,
  v: v,
  r: r,

  map: f => n(l.map(f), f(v), r.map(f)),

  fold: (acc, accf) =>
    accf(accf(accf(acc, l.fold(acc, accf)), v), r.fold(acc, accf)),

  cata: alg => alg.node(l.cata(alg), v, r.cata(alg)),

  accept: visitor => {
    visitor.visitNode(n(l, v, r));
  },

  traverse: (TyperRep, f) =>
    TyperRep(li => vi => ri => n(li, vi, ri))
      .app(l.traverse(TyperRep, f))
      .app(f(v))
      .app(r.traverse(TyperRep, f)),
  foldM: (acc, accfM) => r.foldM(acc, accfM).bind(acc1 => l.foldM(acc1, accfM)),
  foldMap: f => l.foldMap(f).concat(r.foldMap(f))
});

var lf = v => ({
  v: v,
  map: f => lf(f(v)),

  fold: (acc, accf) => accf(acc, v),

  cata: alg => alg.leaf(v),

  traverse: (TyperRep, f) => f(v),

  foldMap: f => f(v),
  foldM: (acc, accfM) => accfM(acc, v)
});

var traverse = function(list, TyperRep, f) {
  if (list.length === 0) {
    return TyperRep([]);
  } else {
    var head = list.shift();
    return TyperRep(x => y => x.concat(y))
      .app(f(head).map(x => [x]))
      .app(traverse(list, TyperRep, f));
  }
};

var dist = function(list, TyperRep) {
  if (list.length === 0) {
    return TyperRep([]);
  } else {
    var head = list.shift();
    return TyperRep(x => y =>...