JSFiddle - React, Tailwind, and code Playground

by dimitrs_papadimitriou

JavaScript

var demo = function () {
  var IO = fn => ({ map: f => IO(() => f(fn())), chain: f =>IO(()=>f(fn()).run()), run:() => fn() });
  var Id = v => ({ v: v, map: f => Id(f(v)), chain: f => f(v), });

  //foldMap :: Monoid m => (a -> m) -> t a -> m
  const Free = {
    Pure: x => ({
      map: f => Free.Pure(f(x)),
      chain: f => f(x),
      foldMap: (_, typeRep) => {
        return typeRep(x);
      }
    }),
    Impure: (command, g) => ({
      map: f => Free.Impure(command, y => g(y).map(f)),
      chain: f => Free.Impure(command, y => g(y).chain(f)),
      foldMap: (interpreter, typeRep) => {
        return command.evaluate(interpreter).chain(result => g(result).foldMap(interpreter, typeRep)); 
      }
    })
  };

  var set = number => Free.Impure(({ evaluate: interpreter => interpreter.set(number) }), Free.Pure);

  var get = Free.Impure(({ evaluate: interpreter => interpreter.get({ v: 5 }) }), Free.Pure);

  var result = get.chain(set);

  var interpreter = {
    v:0,
    get: o => IO(()=>o.v),
    set: o => IO(()=>{interpreter.v=interpreter.v+o})
  };

  var tt = result.foldMap(interpreter, a=>IO(()=>a));
  tt.run() 

  interpreter.get(5).chain( interpreter.set).run()
}



module.exports = demo;