Last active
October 10, 2015 01:00
-
-
Save kazu69/96344bf338061ca75552 to your computer and use it in GitHub Desktop.
Haskell like monad in ES6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var UpperCase = value => { | |
if(!value) return value; | |
return value.toUpperCase(); | |
} | |
var LowerCase = value => { | |
if(!value) return value; | |
return value.toLowerCase(); | |
} | |
// Identity monad | |
Monad.create( | |
Monad.create('hello').bind(UpperCase) | |
).bind(LowerCase) // => hello | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let list = ['a','b']; | |
var beforeAdd = (obj, array) => { | |
var result = []; | |
if(!(obj instanceof Array)) obj = [obj]; | |
obj.forEach(function(item) { | |
var tmp = array.map(function(words) { | |
return words + '-' + item; | |
}); | |
result = result.concat(tmp); | |
}); | |
return result; | |
} | |
var afterAdd = (obj, array) => { | |
var result = []; | |
if(!(obj instanceof Array)) obj = [obj]; | |
obj.forEach(function(item) { | |
var tmp = array.map(function(words) { | |
return item + '-' + words; | |
}); | |
result = result.concat(tmp); | |
}); | |
return result; | |
} | |
// List | |
Monad.create( | |
Monad.create('test').bind(beforeAdd, [list]) | |
).bind(afterAdd, [list]); // => [ 'a-test-a', 'a-test-b', 'b-test-a', 'b-test-b' ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var UpperCase = value => { | |
if(!value) return value; | |
return value.toUpperCase(); | |
} | |
var LowerCase = value => { | |
if(!value) return value; | |
return value.toLowerCase(); | |
} | |
// Maybe | |
Monad.create( | |
Monad.create(null).bind(UpperCase) | |
).bind(LowerCase); // => null |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
class Monad { | |
constructor(value) { | |
if (typeof modifier === 'function') { | |
this._modifier = value; | |
} else { | |
this._value = value; | |
} | |
} | |
static create(func) { | |
return new Monad(func); | |
} | |
value() { | |
if(this._value === undefined) return undefined; | |
return this._value; | |
} | |
bind(func, args) { | |
return func.apply(undefined, [this.value()].concat(Array.prototype.slice.apply(args || []))); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>QUnit Example</title> | |
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-1.19.0.css"> | |
</head> | |
<body> | |
<div id="qunit"></div> | |
<div id="qunit-fixture"></div> | |
<script src="https://code.jquery.com/qunit/qunit-1.19.0.js"></script> | |
<script src="es6.js"></script> | |
<script src="test.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
QUnit.test( '`return x >>= f` should be equal `f a`', function( assert ) { | |
var f = function(a) { return a * 2; } | |
var left = Monad.create(1).bind(f); | |
var right = f(1); | |
assert.equal(left, right, 'left, right is equal'); | |
}); | |
QUnit.test('`m >>= return` should be equal `m`', function( assert ) { | |
var left = Monad.create(Monad.create().value()); | |
var right = Monad.create(); | |
assert.deepEqual(left, right, 'left, right is equal'); | |
}); | |
QUnit.test('`(m >>= f) >>= g` should be equal `m >>= (x -> f x >>= g`', function( assert ) { | |
var f = function f(num) { | |
return num + 1; | |
} | |
var g = function(num) { | |
return num * 2; | |
} | |
var left = Monad.create( Monad.create(1).bind(f) ).bind(g); | |
var right = Monad.create( Monad.create(f(1)).bind(g) ).value(); | |
assert.deepEqual(left, right, 'left, right is equal'); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment