Skip to content

Instantly share code, notes, and snippets.

@svanellewee
Last active August 29, 2015 14:25
Show Gist options
  • Save svanellewee/8d443a64551e2675a2fd to your computer and use it in GitHub Desktop.
Save svanellewee/8d443a64551e2675a2fd to your computer and use it in GitHub Desktop.
Functors just take stuff out of "type-boxes" apply a function and put them back into the same "type-boxes".
/*
*
* Functor :
* fmap : (a -> b) -> fa -> fb
*
*/
function array_fmap1(fn, typeA) {
var typeB = []
typeA.forEach(function(aVal) {
typeB.push(fn(aVal))
});
return typeB;
}
function plus1(x) {
return x+1;
}
function times10(x) {
return x*10;
}
function compose(f,g){
return function(val) {
return f(g(val));
};
}
var val1 = array_fmap1(times10, array_fmap1(plus1, [1,2,3,40]));
console.log(val1);
var val2 = array_fmap1(compose(times10, plus1), [1,2,3,40]);
console.log(val2);
function string_fmap(fn, string) {
var retstring = "";
Array.prototype.forEach.call(string,function(e) {
retstring += fn(e);
});
return retstring;
}
function makeUpperCase(e) {
return e.toUpperCase();
}
var val3 = string_fmap(makeUpperCase,'hello world ');
console.log(val3);
function Maybe(val) {
if ( !(this instanceof Maybe) ){
return new Maybe(val);
}
this.val = val;
}
Maybe.prototype.fmap = function(fn) {
if (this.val === null) {
return new Maybe(null);
}
if (typeof this.val === "undefined") {
return new Maybe(null)
}
return new Maybe(fn(this.val))
}
var m12 = Maybe(12);
var mnull = Maybe(null);
console.log(m12.fmap(plus1).fmap(plus1));
console.log(mnull.fmap(plus1).fmap(plus1));
function Either(valleft, valright){
if (!(this instanceof Either)) {
return new Either(valleft, valright);
}
this.valleft = valleft;
this.valright = valright;
}
Either.prototype.fmap = function(fn) {
if ((this.valright !== null) &&
(typeof this.valright !== 'undefined')) {
return new Either(this.valleft, fn(this.valright));
}
if ((this.valleft !== null) &&
(typeof this.valleft !== 'undefined')) {
return new Either(fn(this.valleft), this.valright);
}
return new Either(this.valleft, this.valright);
}
var res4 = new Either(12,null)
.fmap(plus1)
.fmap(times10);
console.log(res4);
function wasNullResult(x) {
return null;
}
console.log(new Either(12,2)
.fmap(plus1)
.fmap(wasNullResult)
.fmap(plus1));
var addressBla ;
//var addressBla = "Something";
var either = new Either( { address : "Bla"}, addressBla)
.fmap(updateField);
function updateField(x) {
console.log("GETTING ",x);
return x;
}
console.log(addressBla, either);
function Reeks() { // Afrikaans for "array"... see what I did there?
this.value = Array.prototype.slice.call(arguments, 0);
}
Reeks.prototype.fmap = function(fn) {
var vals = [];
this.value.forEach(function(elem) {
//console.log(".",elem);
vals.push(fn(elem));
});
var result = (function apply_args_to_constructor() {
function NewReeks(values) {
return Reeks.apply(this, values);
}
NewReeks.prototype = Reeks.prototype;
return new NewReeks(vals);
})();
return result;
}
var reeks = new Reeks(1,2,3,4);
var result12 = reeks.fmap(plus1);
console.log(reeks);
console.log(result12);
//--- monads ?
var just12 = new Maybe(12);
// a -> M a
function half(x) {
if ( x % 2 === 0 ){
return new Maybe (x / 2); // Just (x/2)
}
return new Maybe (null); // Nothing
}
Maybe.prototype.Bind = function(fn) {
return this.val ? fn(this.val) : Maybe();
}
// class Monad m where
// (>>=) :: m a -> (a -> m b) -> m b
// instance Monad Maybe where
// Nothing >>= func = Nothing
// Just val >>= func = func val
var m3 = new Maybe(3);
console.log(m3.Bind(half));
var m4 = new Maybe(4);
console.log(m4.Bind(half));
var mnull2 = new Maybe(null);
console.log(mnull2.Bind(half));
console.log((new Maybe(20)).Bind(half));
console.log((new Maybe(20)).Bind(half).Bind(half));
//console.log((new Maybe(20)).Bind(half));
// What about promises.. functors ?
// then === fmap ?
//-------
//
// a -> b
function length(x) {
return new Maybe(x.length);
}
function log(x){
console.log("..!!",x);
return new Maybe(x);
}
var result = (new Maybe("hello"))
.Bind(length)
.Bind(log);
var result2 = (new Maybe(null))
.Bind(length)
.Bind(log);
var result = (new Maybe("hello world"))
.fmap(length)
.fmap(log);
var result2 = (new Maybe(null))
.fmap(length)
.fmap(log);
console.log("...");
// string -> Maybe string
function getName(name) {
var lookup = { "stephan" : 12,
"rose" : 100,
"sammy" : 50,
"bella" : 2
};
return new Maybe(lookup[name]);
}
function Sub10(x) {
return new Maybe(x-10);
}
function FilterLessThan10(x) {
var retval = x > 10 ? x : null;
return new Maybe(retval);
}
function Mult2(x) {
return new Maybe(x*2);
}
[ "stephan" , "boris", "bella" ].forEach(function(name) {
var maybeval = getName(name);
maybeval
.Bind(Mult2)
.Bind(Sub10)
.Bind(FilterLessThan10)
.Bind(function(y) {
console.log("val * 2 - 10 = ", y);
return new Maybe(y);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment