JSFiddle - React, Tailwind, and code Playground

by jrab227

JavaScript

// f :: s -> {v, s}
function State(f) {
	this.f = f;
}

State.prototype.run = function(s) {
	return this.f(s);
};

// bind :: State(...) -> (v -> State(...) ) -> State(...);
State.prototype.then = function(k) {
	var self = this;
	return new State(function(s) {
    var newState = self.run(s);
    var holdState = k(newState.value);
    return holdState.run(newState.state);
  });
}

// return :: State(...) -> (v -> State(...) ) -> State(...);
function fill(a) {
	return new State(function(s) {
  	return {value: a, state: s};
  });
}

function insert(v) {
	return function() {
  	return fill(v);
  };
}

function push(v) {
  return new State(function(s) {
    return {value: v, state: s.concat([v])};
  });
}

function pop() {
	return new State(function(s) {
  	return {value: s[0], state: s.slice(1)};
  });
}

// Now that the work is done, check out the nice part!

var j = fill(null)
.then(pop)
.then(pop)
.then(insert(2))
.then(push)
.run([0, 1, 2]);

alert(j.state)