Created
May 21, 2014 21:29
-
-
Save fabioyamate/7074ebceb143f551a70e to your computer and use it in GitHub Desktop.
Playground for a monad maybe implementation in Javascript
This file contains 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 lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>jQuery Snippet</title> | |
</head> | |
<body> | |
<div id="container"></div> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore-contrib/0.1.4/underscore-contrib.min.js"></script> | |
<script> | |
function Just(value) { | |
return { | |
value: value, | |
bind: function(f) { | |
return f(this.value); | |
}, | |
unit: Just | |
}; | |
} | |
function Nothing() { return Nothing; } | |
Nothing.bind = function() { | |
return Nothing; | |
} | |
// liftM :: Monad m => (a1 -> r) -> m a1 -> m r | |
function liftM(f, m) { | |
return m.bind(function(i) { | |
return m.unit(f(i)); | |
}); | |
} | |
// liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r | |
function liftM2(f, m1, m2) { | |
return m1.bind(function(i) { | |
return m2.bind(function(j) { | |
return m1.unit(f(i, j)); | |
}); | |
}); | |
} | |
// liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r | |
function liftM3(f, m1, m2, m3) { | |
return m1.bind(function(i) { | |
return m2.bind(function(j) { | |
return m3.bind(function(k) { | |
return m1.unit(f(i, j, k)); | |
}); | |
}); | |
}); | |
} | |
var phonebook = 1; | |
var governamentalDatabase = 2; | |
var taxDatabase = 3; | |
// lookup :: String -> ... -> Maybe | |
function lookup(name, database) { | |
if (database == 1) { | |
console.log('1'); | |
return Nothing; | |
} else if (database == 2) { | |
console.log('2'); | |
return Just('registration'); | |
} else if (database == 3) { | |
console.log('3'); | |
return Just('number'); | |
} | |
} | |
function getTaxOwed(name) { | |
return lookup(name, phonebook).bind(function(number) { | |
return lookup(number, governamentalDatabase).bind(function(registration) { | |
return lookup(registration, taxDatabase); | |
}); | |
}); | |
} | |
// getTaxOwed :: String -> Maybe | |
// do | |
// number <- lookup(name, phonebook) | |
// registration <- lookup(number, go...) | |
// lookup(registration, taxDatab) | |
// => Just(tax) | |
// lookup(name, phonebook) >>= \number | |
// -> lookup(number, gover) >>= \registration | |
// -> lookup(registration, taxDatabase) | |
// do | |
// x <-Just(3) | |
// y <- Just(4) | |
// return $ x + y | |
console.log(getTaxOwed('fabio')); | |
function sum(a, b) { | |
return a + b; | |
} | |
console.log(liftM2(sum, Just(3), Nothing)); | |
function Try(expr) { | |
try { | |
return Success(expr); | |
} catch(e) { | |
return Failure(e); | |
} | |
} | |
function Success(expr) { | |
var value = expr(); | |
return { | |
bind: function(f) { | |
try { | |
return f(value); | |
} catch (e) { | |
return Failure(e); | |
} | |
} | |
}; | |
} | |
function Failure(exception) { | |
return { | |
bind: function() { | |
return exception; | |
} | |
}; | |
} | |
parseNumber = function(v) { | |
var value = parseInt(v, 10); | |
if (value === NaN) { | |
throw 'a'; | |
} else { | |
return value; | |
} | |
} | |
var a = Try(function() { return parseNumber("1") }).bind(function(a) { | |
return Try(function() { return parseNumber("2") }).bind(function(b) { | |
return Try(a + b); | |
}); | |
}); | |
console.log(a); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment