├── LICENSE ├── README.md ├── examples ├── arrayMonad.js ├── identitymonad.js ├── maybemonad.js └── statemonad.js ├── lib └── monadjs.js └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Santosh Rajan 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # monadjs 2 | 3 | ## Monad Library for JavaScript 4 | 5 | ### Install 6 | $ npm install monadjs 7 | 8 | ### Usage 9 | #### Nodejs 10 | var monads = require("monadjs"); 11 | #### Browser 12 | Use [browserify](http://browserify.org/) to use in browser. 13 | 14 | Note: Latest version "0.1.0" is not compatible with the previous versions "0.0.6" 15 | 16 | ### Docs 17 | 18 | #### Available monads 19 | 20 | monads.identity // Identity Monad 21 | monads.mayBe // Maybe Monad 22 | monads.array // Array Monad 23 | monads.state // State Monad 24 | monads.continuation // Continuation Monad 25 | monads.parser // Parser Monad 26 | monads.do // is the doMonad function 27 | 28 | See examples folder. 29 | 30 | See the following blogpost for usage and explanation. [http://functionaljavascript.blogspot.in/2013/07/monads.html](http://functionaljavascript.blogspot.in/2013/07/monads.html) 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/arrayMonad.js: -------------------------------------------------------------------------------- 1 | var monads = require("monadjs"); 2 | 3 | function forEach3D(iArray, jArray, kArray, callback) { 4 | return monads.do(monads.array, [iArray, jArray, kArray], callback) 5 | } 6 | 7 | var result = forEach3D([1, 2], [3, 4], [5, 6], function(i, j, k) { 8 | return i + j + k 9 | }) 10 | 11 | console.log(result) 12 | -------------------------------------------------------------------------------- /examples/identitymonad.js: -------------------------------------------------------------------------------- 1 | var monads = require("monadjs") 2 | 3 | var result = monads.do(monads.identity, [1, 2], function(a, b) { 4 | return a + b 5 | }) 6 | 7 | console.log(result); -------------------------------------------------------------------------------- /examples/maybemonad.js: -------------------------------------------------------------------------------- 1 | var monads = require("monadjs") 2 | 3 | // will return 6 on nodejs null on browser 4 | var result = monads.do(monads.mayBe, 5 | [ 6 | typeof global === "object" ? 2 : null, 7 | 3 8 | ], 9 | function(a, b) {return a * b} 10 | ) 11 | console.log(result); 12 | 13 | // will return 6 on browser null on nodejs 14 | var result = monads.do(monads.mayBe, 15 | [ 16 | typeof window === "object" ? 2 : null, 17 | 3 18 | ], 19 | function(a, b) {return a * b} 20 | ) 21 | 22 | console.log(result); -------------------------------------------------------------------------------- /examples/statemonad.js: -------------------------------------------------------------------------------- 1 | var monads = require("monadjs"); 2 | 3 | var push = function(element) { 4 | return function(state) { 5 | var newstate = [element] 6 | return [undefined, newstate.concat(state)] 7 | } 8 | } 9 | 10 | var pop = function() { 11 | return function(state) { 12 | var newstate = state.slice(1) 13 | return [state[0], newstate] 14 | } 15 | } 16 | 17 | var result = monads.do(monads.state, 18 | [ 19 | push(5), 20 | push(10), 21 | push(20), 22 | pop() 23 | ], 24 | function(val1, val2, val3, val4) { 25 | return val4 26 | } 27 | ) 28 | 29 | 30 | console.log(result([])) -------------------------------------------------------------------------------- /lib/monadjs.js: -------------------------------------------------------------------------------- 1 | /* 2 | monadjs 3 | Monad Library for JavaScript 4 | Copyright (c) 2013 Santosh Rajan 5 | License - MIT - https://github.com/santoshrajan/monadjs/blob/master/LICENSE 6 | */ 7 | 8 | exports.version = "0.1.0" 9 | 10 | // Curry function 11 | 12 | function curry(fn, numArgs) { 13 | numArgs = numArgs || fn.length 14 | return function f(saved_args) { 15 | return function() { 16 | var args = saved_args.concat(Array.prototype.slice.call(arguments)) 17 | return args.length === numArgs ? fn.apply(null, args) : f(args) 18 | } 19 | }([]) 20 | } 21 | 22 | // The identity Monad 23 | 24 | function identityMonad(mv, mf) { 25 | return mf(mv) 26 | } 27 | identityMonad.mResult = function(v) { 28 | return v 29 | } 30 | 31 | // The mayBe Monad 32 | 33 | function mayBeMonad(mv, mf) { 34 | return mv === null || mv === undefined || mv === false ? null : mf(mv) 35 | } 36 | mayBeMonad.mResult = function(v) { 37 | return v 38 | } 39 | 40 | // The array Monad 41 | 42 | function arrayMonad(mv, mf) { 43 | var result = [] 44 | mv.forEach(function(v) { 45 | Array.prototype.push.apply(result, mf(v)) 46 | }) 47 | return result 48 | } 49 | arrayMonad.mResult = function(v) { 50 | return [v] 51 | } 52 | 53 | // The state Monad 54 | 55 | function stateMonad(mv, mf) { 56 | return function(state) { 57 | var compute = mv(state) 58 | return mf(compute[0])(compute[1]) 59 | } 60 | } 61 | stateMonad.mResult = function(value) { 62 | return function(state) { 63 | return [value, state]; 64 | } 65 | } 66 | 67 | // The parser Monad 68 | 69 | function parserMonad(mv, mf) { 70 | return function(str) { 71 | var compute = mv(str) 72 | if (compute === null) { 73 | return null 74 | } else { 75 | return mf(compute[0])(compute[1]) 76 | } 77 | } 78 | } 79 | parserMonad.mResult = function(value) { 80 | return function(str) { 81 | return [value, str]; 82 | } 83 | } 84 | parserMonad.mZero = function(str) { 85 | return null 86 | } 87 | parserMonad.mPlus = function() { 88 | var parsers = Array.prototype.slice.call(arguments) 89 | return function(str) { 90 | var result, i 91 | for (i = 0; i < parsers.length; ++i) { 92 | result = parsers[i](str) 93 | if (result !== null) { 94 | break; 95 | } 96 | } 97 | return result 98 | } 99 | } 100 | 101 | // The continuation Monad 102 | 103 | function continuationMonad(mv, mf) { 104 | return function(continuation) { 105 | return mv(function(value) { 106 | return mf(value)(continuation); 107 | }) 108 | } 109 | } 110 | continuationMonad.mResult = function(value) { 111 | return function(continuation) { 112 | return continuation(value) 113 | } 114 | } 115 | 116 | function doMonad(monad, values, cb) { 117 | function wrap(curriedCb, index) { 118 | return function mf(v) { 119 | return (index === values.length - 1) ? 120 | monad.mResult(curriedCb(v)) : 121 | monad(values[index + 1], wrap(curriedCb(v), index + 1)) 122 | } 123 | } 124 | return monad(values[0], wrap(curry(cb), 0)) 125 | } 126 | 127 | 128 | 129 | exports.identity = identityMonad 130 | exports.mayBe = mayBeMonad 131 | exports.array = arrayMonad 132 | exports.state = stateMonad 133 | exports.parser = parserMonad 134 | exports.continuation = continuationMonad 135 | exports.do = doMonad 136 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "monadjs", 3 | "description" : "Monad Library for JavaScript.", 4 | "keywords" : ["monads", "functional", "javascript", "server", "client", "browser"], 5 | "author" : "Santosh Rajan ", 6 | "repository" : {"type": "git", "url": "git://github.com/santoshrajan/monadjs.git"}, 7 | "main" : "lib/monadjs.js", 8 | "version" : "0.1.0", 9 | "license" : "MIT" 10 | } --------------------------------------------------------------------------------