{"id":22929051,"url":"https://github.com/teaentitylab/fpes","last_synced_at":"2026-03-07T18:31:28.544Z","repository":{"id":32519721,"uuid":"135992999","full_name":"TeaEntityLab/fpEs","owner":"TeaEntityLab","description":"Functional Programming for EcmaScript(Javascript)","archived":false,"fork":false,"pushed_at":"2023-10-12T08:44:24.000Z","size":2843,"stargazers_count":42,"open_issues_count":5,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-18T04:22:16.794Z","etag":null,"topics":["curry","currying","es","es6","es7","fp","functional-programming","functional-reactive-programming","javascript","js","monad","monads","optional","optional-implementations","publisher-subscriber","publisher-subscriber-pattern","pubsub","reactive","reactive-programming","rx"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TeaEntityLab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-06-04T08:17:16.000Z","updated_at":"2025-02-11T21:57:51.000Z","dependencies_parsed_at":"2024-01-02T23:42:32.649Z","dependency_job_id":"8ecf2a70-a396-41f1-9806-ea32cd656f9b","html_url":"https://github.com/TeaEntityLab/fpEs","commit_stats":{"total_commits":477,"total_committers":4,"mean_commits":119.25,"dds":"0.46540880503144655","last_synced_commit":"540b882db14d0e52cb5df08d15ea9774fc67397e"},"previous_names":[],"tags_count":64,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeaEntityLab%2FfpEs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeaEntityLab%2FfpEs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeaEntityLab%2FfpEs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeaEntityLab%2FfpEs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TeaEntityLab","download_url":"https://codeload.github.com/TeaEntityLab/fpEs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253860048,"owners_count":21975211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["curry","currying","es","es6","es7","fp","functional-programming","functional-reactive-programming","javascript","js","monad","monads","optional","optional-implementations","publisher-subscriber","publisher-subscriber-pattern","pubsub","reactive","reactive-programming","rx"],"created_at":"2024-12-14T09:29:07.317Z","updated_at":"2025-10-28T05:43:52.026Z","avatar_url":"https://github.com/TeaEntityLab.png","language":"JavaScript","readme":"# fpEs\n\n[![npm download](https://img.shields.io/npm/dt/fpes.svg)](https://www.npmjs.com/package/fpes)\n[![npm version](https://img.shields.io/npm/v/fpes.svg)](https://www.npmjs.com/package/fpes)\n[![codecov](https://codecov.io/gh/TeaEntityLab/fpEs/branch/master/graph/badge.svg)](https://codecov.io/gh/TeaEntityLab/fpEs)\n[![Travis CI Build Status](https://travis-ci.com/TeaEntityLab/fpEs.svg?branch=master)](https://travis-ci.com/TeaEntityLab/fpEs)\n\n[![license](https://img.shields.io/github/license/TeaEntityLab/fpEs.svg?style=social\u0026label=License)](https://github.com/TeaEntityLab/fpEs)\n[![stars](https://img.shields.io/github/stars/TeaEntityLab/fpEs.svg?style=social\u0026label=Stars)](https://github.com/TeaEntityLab/fpEs)\n[![forks](https://img.shields.io/github/forks/TeaEntityLab/fpEs.svg?style=social\u0026label=Fork)](https://github.com/TeaEntityLab/fpEs)\n\n\nFunctional Programming for EcmaScript(Javascript)\n\n# Why\n\nOriginally I would like to have some features of Optional \u0026 Rx-like \u0026 PubSub functions;\n\nhowever somehow that's too heavy if including them at the same time.\n\nThus the implementation just includes the core functions, and more clear to use.\n\n## Special thanks:\n  * [purify](https://github.com/gigobyte/purify) (Inspiration from parts of Maybe implementations for [Fantasy-Land Specs](https://github.com/fantasyland/fantasy-land))\n\n# Installation\n\n## Node.js\n\nnode \u003e= 6.0\n\n* Installation:\n\n```bash\nnpm i fpes\n```\n\n## Browser\n\nbundled files for web/browser usages:\n\n[all](https://unpkg.com/fpes/dist/bundle.min.js)\n\n---\n\n[fp](https://unpkg.com/fpes/dist/fp.min.js)\n\n[maybe](https://unpkg.com/fpes/dist/maybe.min.js)\n\n[monadio](https://unpkg.com/fpes/dist/monadio.min.js)\n\n[pattern](https://unpkg.com/fpes/dist/pattern.min.js)\n\n[publisher](https://unpkg.com/fpes/dist/publisher.min.js)\n\n# Usage\n\n## Import\n\n* You can include the entire library:\n\n```javascript\nimport fpEs from 'fpEs';\n```\n\n* There are 5 modules in this library, you can include them individually:\n  * Facades:\n    * maybe\n    * monadio\n    * publisher\n  * FP functions:\n    * fp\n    * pattern\n\nJust include things you need:\n\n```javascript\nimport {Maybe} from \"fpEs\";\n// or this one:\n/*\nimport Maybe from \"fpEs/maybe\";\n*/\n\nvar m = Maybe.just(1); // It works\n```\n\nor\n\n```javascript\nimport {\n  compose, curry,\n} from \"fpEs\";\n```\n\nor\n\n```javascript\nimport {\n  compose, curry,\n} from \"fpEs/fp\";\n```\n\n## Common FP (Compose, Curry)\n\nExample:\n\n```javascript\n\nimport {\n  compose, curry,\n} from \"fpEs/fp\";\n\n// compose\n\nconsole.log(compose((x)=\u003ex-8, (x)=\u003ex+10, (x)=\u003ex*10)(4)) // 42\nconsole.log(compose((x)=\u003ex+2, (x,y)=\u003ex*y)(4,10)) // 42\n\n// curry\n\nconsole.log(curry((x, y, z) =\u003e x + y + z)(1,2,3)) // 6\nconsole.log(curry((x, y, z) =\u003e x + y + z)(1)(2,3)) // 6\nconsole.log(curry((x, y, z) =\u003e x + y + z)(1,2)(3)) // 6\nconsole.log(curry((x, y, z) =\u003e x + y + z)(1)(2)(3)) // 6\n\n```\n\n## PatternMatching\n\nExample:\n\n```javascript\n\nimport {\n  either,\n  inCaseOfObject, inCaseOfEqual, inCaseOfClass, otherwise,\n\n  SumType, ProductType, CompType,\n  TypeNumber,\n  TypeString,\n  TypeNaN,\n  TypeObject,\n  TypeArray,\n  TypeNull,\n  TypeEqualTo,\n  TypeClassOf,\n  TypeRegexMatches,\n} from \"fpEs/pattern\";\n\n// PatternMatching\n\nconsole.log(either({}, inCaseOfObject((x)=\u003eJSON.stringify(x)), otherwise((x)=\u003efalse))); // \"{}\"\nconsole.log(either([], inCaseOfObject((x)=\u003eJSON.stringify(x)), otherwise((x)=\u003efalse))); // false\nconsole.log(either(null, inCaseOfObject((x)=\u003eJSON.stringify(x)), otherwise((x)=\u003efalse))); // false\nconsole.log(either(undefined, inCaseOfObject((x)=\u003eJSON.stringify(x)), otherwise((x)=\u003efalse))); // false\nconsole.log(either(\"\", inCaseOfObject((x)=\u003eJSON.stringify(x)), otherwise((x)=\u003efalse))); // false\n\n// otherwise\n\nvar err = undefined;\n\nerr = undefined;\neither(1, inCaseOfEqual(1, (x)=\u003ex+1)).should.equal(2);\n(err === undefined).should.equal(true);\n\nerr = undefined;\ntry {\n  either(1, inCaseOfEqual(2, (x)=\u003ex+1));\n} catch (e) {\n  err = e;\n}\n(err === undefined).should.equal(false);\n\nerr = undefined;\ntry {\n  either(1, inCaseOfEqual(2, (x)=\u003ex+1), otherwise((x)=\u003ex+2)).should.equal(3);\n} catch (e) {\n  err = e;\n  console.log(e);\n}\n(err === undefined).should.equal(true);\n\n// SumType\n\nvar s;\ns = new SumType(new ProductType(TypeString, TypeNumber), new ProductType(TypeRegexMatches('c+')));\nconsole.log(s.apply(\"1\", \"2asdf\") === undefined); // true\nconsole.log(s.apply(\"1\", 2) === undefined); // false\n\nconsole.log(s.apply(\"1\") === undefined); // true\nconsole.log(s.apply(\"ccc\") === undefined); // false\n\n```\n\n## Maybe (Sync)\n\nExample:\n\n```javascript\n\nimport Maybe from \"fpEs/maybe\";\n\nvar m;\n\n// map (sync)\n\nm = Maybe.just(1).map((x)=\u003ex+2).map((x)=\u003ex+3);\nconsole.log(m.unwrap()); // 6\n\n// isPresent/isNull\n\nm = Maybe.just(1);\nconsole.log(m.isPresent()); // true\nconsole.log(m.isNull()); // false\nm = Maybe.just(null);\nconsole.log(m.isPresent()); // false\nconsole.log(m.isNull()); // true\nm = Maybe.just(undefined);\nconsole.log(m.isPresent()); // false\nconsole.log(m.isNull()); // true\n\n// Or\n\nm = Maybe.just(1);\nconsole.log(m.or(3).unwrap()); // 1\nconsole.log(m.or(4).unwrap()); // 1\nm = Maybe.just(null);\nconsole.log(m.or(3).unwrap()); // 3\nconsole.log(m.or(4).unwrap()); // 4\nm = Maybe.just(undefined);\nconsole.log(m.or(3).unwrap()); // 3\nconsole.log(m.or(4).unwrap()); // 4\n\n// letDo\n\nm = Maybe.just(1);\nv = 0;\nm.letDo(function () {\n  v = 1;\n});\nconsole.log(v); // 1\nm = Maybe.just(null);\nv = 0;\nm.letDo(function () {\n  v = 1;\n});\nconsole.log(v); // 0\nm = Maybe.just(undefined);\nv = 0;\nm.letDo(function () {\n  v = 1;\n});\nconsole.log(v); // 0\n\n// letDo \u0026 orDo\nm = Maybe.just(0);\nv = m.letDo(function (p) {\n  return p + 2\n}).orDo(function () {\n  return 3\n}).unwrap();\nconsole.log(v); // 2\nm = Maybe.just(undefined);\nv = m.letDo(function (p) {\n  return p + 2\n}).orDo(function () {\n  return 3\n}).unwrap();\nconsole.log(v); // 3\n\n```\n\n## MonadIO/Rx.Observable (Async,Sync)\n\nExample:\n\n```javascript\n\nimport Maybe from \"fpEs/maybe\";\nimport MonadIO from \"fpEs/monadio\";\nvar {promiseof, doM} = MonadIO;\n\n\n\nvar p = undefined;\nvar m = MonadIO.just(0);\nvar v = 0;\n\n// sync\n\nm = MonadIO.just(0);\nv = 0;\nm\n.map((val)=\u003eval+1)\n.map((val)=\u003eval+2)\n.flatMap((val)=\u003eMonadIO.just(val+1).map((val)=\u003eval+1).map((val)=\u003eval+1))\n.subscribe((val)=\u003ev=val);\n\nconsole.log(v); // 6\n\n// async\n\nm = MonadIO.just(0);\nv = 0;\np = m\n.map((val)=\u003eval+1)\n.map((val)=\u003eval+2)\n.map((val)=\u003eval+3)\n.subscribe((val)=\u003ev=val, true); // Async: true\n\nconsole.log(v); // 0\np.then(function () {\n  console.log(v); // 6\n});\n\n// DoNotation\n\nv = 0;\np = doM(function *() {\n  var value = yield promiseof(5);\n  var value2 = yield promiseof(11);\n  var value3 = yield Maybe.just(3);\n  var value4 = yield MonadIO.just(3);\n  return value + value2 + value3 + value4;\n});\n\np.then((x)=\u003econsole.log(x)); // 22\n\n```\n\n## Publisher(PubSub-like)\n\nExample:\n\n```javascript\n\nimport Publisher from \"fpEs/publisher\";\n\nvar p = new Publisher();\nvar v = 0;\n\n// sync\n\np = new Publisher();\nv = 0;\np.subscribe((i)=\u003ev=i);\np.publish(1);\n\nconsole.log(v); // 1\n\n// async\n\np = new Publisher();\nv = 0;\n\np.subscribe((i)=\u003ev=i);\np.publish(1, true); // Async: true\nconsole.log(v); // 0\n\nsetTimeout(()=\u003e{\n  console.log(v); // 1\n},100);\n\n// map\n\np = new Publisher();\nv = 0;\n\np.map((x)=\u003ex+2).map((x)=\u003ex+3).subscribe((i)=\u003ev=i);\np.publish(1, true);\nconsole.log(v); // 0\n\nsetTimeout(()=\u003e{\n  console.log(v); // 6\n},100);\n\n// unsubscribe\n\np = new Publisher();\nv = 0;\nvar callback = (i)=\u003ev=i;\n\np.subscribe(callback);\np.publish(1);\nconsole.log(v); // 1\nv = 0;\np.unsubscribe(callback);\np.publish(1);\nconsole.log(v); // 0\n\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteaentitylab%2Ffpes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteaentitylab%2Ffpes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteaentitylab%2Ffpes/lists"}