My First Functor

https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch8.html

HTML

<script src="//cdn.jsdelivr.net/ramda/0.19/ramda.min.js"></script>

TypeScript

const _ = R;

class Container {
	static of(x): Container { 
		return new Container(x); 
	}
	
	constructor(private __value: any) {
	}
	
	// (a -> b) -> Container a -> Container b
	map(f: Function): Container {
		return Container.of(f(this.__value))
	}
}

class Maybe {
	static of(x): Container { 
		return new Maybe(x); 
	}
	
	constructor(private __value: any) {
	}
	
	isNothing() {
		return (this.__value === null || this.__value === undefined);
	}
	
	map(f: Function): Container {
		return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this.__value));
	}
}

class Left {
	static of(x): Left { 
		return new Left(x); 
	}
	
	constructor(private __value: any) {
	}
	
	map(f: Function): Container {
		return this;
	}
}

class Right {
	static of(x): Left { 
		return new Right(x); 
	}
	
	constructor(private __value: any) {
	}
	
	map(f: Function): Container {
		return Right.of(f(this.__value));
	}
}

class IO {
	static of(x: Function): IO {
		return new IO(() => x);
	}
	
	constructor(private unsafePerformIO: Function): void {
	}
	
	map(f: Function): IO {
		return new IO(_.compose(f, this.unsafePerformIO));
	}
}

var safeHead = function(xs: any[]) {
  return Maybe.of(xs[0]);
};

//  url :: IO String
var url = new IO(function() { return window.location.href; });

//  toPairs =  String -> [[String]]
var toPairs = _.compose(_.map(_.split('=')), _.split('&'));

//  params :: String -> [[String]]
var params = _.compose(toPairs, _.last, _.split('?'));

//  findParam :: String -> IO Maybe [String]
var findParam = function(key) {
  return _.map(_.compose(Maybe.of, _.filter(_.compose(_.equals(key), _.head)), params), url);
};

////// Impure calling code: main.js ///////

//container1 = Container.of(3);
//container2 = Container.of("hotdogs");
//container3 = Container.of(Container.of({name: "yoda"}));

//console.debug(container1);
//console.debug(container2);
//console.debug(container3);
//console.debug(Container.of(2).map((two) => two +...