{"id":20356310,"url":"https://github.com/patrimart/monadness-js","last_synced_at":"2025-04-12T02:51:20.430Z","repository":{"id":57301443,"uuid":"67671110","full_name":"patrimart/monadness-js","owner":"patrimart","description":"Implements Either, Maybe and Tuple monads.","archived":false,"fork":false,"pushed_at":"2017-04-30T21:21:33.000Z","size":71,"stargazers_count":33,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-25T22:35:37.525Z","etag":null,"topics":["either","maybe","monads","tuples","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patrimart.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-09-08T05:23:53.000Z","updated_at":"2024-05-09T19:14:39.000Z","dependencies_parsed_at":"2022-09-03T12:13:24.692Z","dependency_job_id":null,"html_url":"https://github.com/patrimart/monadness-js","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrimart%2Fmonadness-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrimart%2Fmonadness-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrimart%2Fmonadness-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrimart%2Fmonadness-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrimart","download_url":"https://codeload.github.com/patrimart/monadness-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248509317,"owners_count":21115989,"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":["either","maybe","monads","tuples","typescript"],"created_at":"2024-11-14T23:15:55.985Z","updated_at":"2025-04-12T02:51:20.404Z","avatar_url":"https://github.com/patrimart.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\r\n[![Build Status](https://travis-ci.org/patrimart/monadness-js.svg?branch=master)](https://travis-ci.org/patrimart/monadness-js)\r\n[![Coverage Status](https://coveralls.io/repos/github/patrimart/monadness-js/badge.svg?branch=master)](https://coveralls.io/github/patrimart/monadness-js?branch=master)\r\n[![npm version](https://badge.fury.io/js/monadness.svg)](https://badge.fury.io/js/monadness)\r\n\r\n# monadness-js\r\n\r\nA TypeScript/JavaScript library that implements some basic \"objects\" of functional programming.\r\n\r\n- [Either](#either)\r\n- [Maybe](#maybe)\r\n- [Tuples](#tuples)\r\n- Option (deprecated for Maybe)\r\n\r\nThe advantages of using these classes:\r\n\r\n- Code that's easier to reason about.\r\n- Better error handling.\r\n- Avoid `null` and `undefined` issues.\r\n\r\n\r\n## Install\r\n\r\n`npm i -S monadness`\r\n\r\n\r\n## Quick Examples\r\n\r\nExample code for `Maybe`:\r\n\r\n```js\r\nimport { Maybe } from \"monadness\";\r\n\r\nfunction getFileContents (filePath: string): Maybe\u003cstring\u003e {\r\n    /* Code to sync read file */\r\n    return Maybe.fromNull(contents);\r\n}\r\n\r\nconst contents = getFileContents(\"path/to/filename.json\");\r\n\r\nif (contents.isDefined()) {\r\n    console.log(\"File contents:\", contents.get());\r\n} else {\r\n    console.error(\"File error: File not loaded.\");\r\n}\r\n\r\nconsole.log(\"File contents:\", contents.getOrElseGet(\"\"));\r\n```\r\n\r\nExample code for `Either`:\r\n\r\n```js\r\nimport { Either } from \"monadness\";\r\n\r\nfunction getFileContents (filePath: string): Either\u003cError, string\u003e {\r\n\r\n    /* Code to sync read file */\r\n\r\n    if (contents === undefined) {\r\n        return Either.left\u003cError, string\u003e(new Error(`File ${filePath} not found.`);\r\n    } else {\r\n        return Either.right\u003cError, string\u003e(contents);\r\n    }\r\n}\r\n\r\nconst contents = getFileContents(\"path/to/filename.json\");\r\n\r\nif (contents.isRight()) {\r\n    console.log(\"File contents:\", contents.get());\r\n} else {\r\n    console.error(\"File error:\", contents.getLeft());\r\n}\r\n\r\ncontents.cata(\r\n    content =\u003e console.log(\"File contents:\", content),\r\n    err =\u003e console.error(\"File error:\", err),\r\n);\r\n```\r\n\r\nExample code for `Tuples`:\r\n\r\n```js\r\nimport { Tuples } from \"monadness\";\r\n\r\nconst tuple = Tuples.from(1, \"two\", true);\r\n\r\nconst [a, b, c] = tuple;\r\nconsole.log(a, b, c);\r\n// 1, \"two\", true\r\n\r\nconst newTuple1 = tuple.map(a =\u003e a + a);\r\nconsole.log(newTuple1._1, newTuple1._2, newTuple1._3);\r\n// 2, \"twotwo\", 2\r\n\r\nconst newTuple2 = tuple.mbind(Tuples.from(\r\n    a =\u003e Tuples.from(a + a),\r\n    b =\u003e Tuples.from(b + \"three\"),\r\n    c =\u003e Tuples.from(!! c),\r\n));\r\nconsole.log(newTuple2._1, newTuple2._2, newTuple2._3);\r\n// 2, \"twothree\", false\r\n```\r\n\r\n\r\n## Usage\r\n\r\n**TypeScript / ES6**\r\n\r\n```js\r\nimport { Either, Maybe, Tuples } from \"monadness\";\r\n```\r\n\r\n**NodeJS**\r\n\r\n```js\r\nconst Monadness = require(\"monadness\"),\r\n      Either = Monadness.Either,\r\n      Maybe = Monadness.Maybe,\r\n      Tuples = Monadness.Tuples;\r\n```\r\n\r\n**Browser**\r\n\r\n```html\r\n\u003cscript src=\"node_modules/dist/monadness.min.js\"\u003e\u003c/script\u003e\r\n\u003cscript src=\"node_modules/dist/monadness.es6.min.js\"\u003e\u003c/script\u003e\r\n```\r\n\r\n\r\n---\r\n\r\n# Maybe\r\n\r\nThe Maybe class can be an instance with a defined value (Maybe.Just) or no value (Maybe.None).\r\n\r\nThis is a better alternative to throwing errors or returning `undefined` values.\r\nIt lets the type-checker discover errors at compile time.\r\n\r\n\r\n## Static Methods\r\n\r\n### Maybe.just\r\n\r\nCreates a Maybe.Just with the given value.\r\n\r\n```js\r\nMaybe.just \u003cT\u003e (value: T): Maybe\u003cT\u003e\r\n```\r\n\r\n### Maybe.none\r\n\r\nCreates a Maybe.None.\r\n\r\n```js\r\nMaybe.none \u003cT\u003e (): Maybe\u003cT\u003e\r\n```\r\n\r\n### Maybe.nothing\r\n\r\nReturns the Maybe.nothing singleton.\r\n\r\n```js\r\nMaybe.nothing (): Maybe\u003cvoid\u003e\r\n```\r\n\r\n### Maybe.fromNull\r\n\r\nCreates a Maybe.Just with the given value or, if the value is `null` or `undefined`, a Maybe.None.\r\n\r\n```js\r\nMaybe.fromNull \u003cT\u003e (value: T | undefined | null): Maybe\u003cT\u003e\r\n```\r\n\r\n### Maybe.sequence\r\n\r\nTurns an array of Maybes into a Maybe of arrays.\r\n\r\n```js\r\nMaybe.sequence \u003cT\u003e (...maybes: Array\u003cMaybe\u003cT\u003e\u003e): Maybe\u003cT[]\u003e\r\n```\r\n\r\n### Maybe.traverse\r\n\r\nMaps an array into a Maybe of arrays.\r\n\r\n```js\r\nMaybe.traverse \u003cT, U\u003e (f: (a: T) =\u003e Maybe\u003cU\u003e): (as: T[]) =\u003e Maybe\u003cU[]\u003e\r\n```\r\n\r\n### Maybe.lift\r\n\r\n```js\r\nMaybe.lift \u003cT\u003e (partialFunction: (...args: any[]) =\u003e T): (...args: any[]) =\u003e Maybe\u003cT\u003e\r\n```\r\n\r\n\r\n## Instance Methods\r\n\r\n### isEmpty\r\n\r\nReturns true if this is a Maybe.None.\r\n\r\n```js\r\nisEmpty (): boolean\r\n```\r\n\r\n### isDefined\r\n\r\nReturns true if this is a Maybe.Right.\r\n\r\n```js\r\nisDefined (): boolean\r\n```\r\n\r\n### get\r\n\r\nReturns the Just value or throws an error if None.\r\n\r\n```js\r\nget (): T | never\r\n```\r\n\r\n### getOrElse\r\n\r\nReturns the Just value or the result of the given function. \r\n\r\n```js\r\ngetOrElse (value: () =\u003e T): T\r\n```\r\n\r\n### getOrElseGet\r\n\r\nReturns the Just value or the given value.\r\n\r\n```js\r\ngetOrElseGet (value: T): T\r\n```\r\n\r\n### getOrThrow\r\n\r\nReturns the Just value or throws the given error.\r\n\r\n```js\r\ngetOrThrow (err?: Error): T | never\r\n```\r\n\r\n### orElse\r\n\r\nReturns the Just value or the function result.\r\n\r\n```js\r\norElse (o: () =\u003e Maybe\u003cT\u003e): Maybe\u003cT\u003e\r\n```\r\n\r\n### map\r\n\r\nApplies the Maybe function to the value and return the result wrapped in a Maybe.\r\n\r\n```js\r\nmap \u003cU\u003e (f: (a: T) =\u003e U): Maybe\u003cU\u003e\r\n```\r\n\r\n### fmap\r\n\r\nApplies the function to the value and return the result.\r\n\r\n```js\r\nfmap \u003cU\u003e (f: (a: T) =\u003e Maybe\u003cU\u003e): Maybe\u003cU\u003e\r\n```\r\n\r\n### applies\r\n\r\n```js\r\napplies \u003cU, V\u003e (f: (a: T) =\u003e (b: U) =\u003e Maybe\u003cV\u003e): (mb: Maybe\u003cU\u003e) =\u003e Maybe\u003cV\u003e\r\n```\r\n\r\n### mbind\r\n\r\nApplies the Maybe function to the value and return the result.\r\n\r\n```js\r\nmbind \u003cU\u003e (f: Maybe\u003c(a: T) =\u003e Maybe\u003cU\u003e\u003e): Maybe\u003cU\u003e\r\n```\r\n\r\n### flatten\r\n\r\nConverts a Maybe of nested Maybes to a one-depth Maybe.\r\n\r\n```js\r\nflatten \u003cU\u003e (): Maybe\u003cU\u003e\r\n```\r\n\r\n### toEither\r\n\r\nConverts the Maybe to an Either.\r\n\r\n```js\r\ntoEither (): Either.Right\u003cError, T\u003e\r\n```\r\n\r\n### toObject\r\n\r\nReturns an object or null.\r\n\r\n```js\r\ntoObject (): { just: T | null; }\r\n```\r\n\r\n### toJSON\r\n\r\nReturns an object or null.\r\n\r\n```js\r\ntoJSON (): { just: T | null }\r\n```\r\n\r\n### toString\r\n\r\nReturns a string representation of the Maybe: '{ \"just\": T }'\r\n\r\n```js\r\ntoString (): string\r\n```\r\n\r\n### equals\r\n\r\nTests the equality of two Maybes.\r\n\r\n```js\r\nequals (other: Maybe\u003cT\u003e): boolean\r\n```\r\n\r\n---\r\n\r\n# Either\r\n\r\nAn Either can hold one of two values, a Left or Right value. Conventionly, a success is a right value and\r\nan error is a left value. (Right is right and left is wrong.)\r\n\r\nThis is a better alternative to throwing errors or returning `undefined` values.\r\nIt lets the type-checker discover errors at compile time.\r\n\r\n\r\n### Static Methods\r\n\r\n### right\r\n\r\nReturns an Either.Right with the given value.\r\n\r\n```js\r\nEither.right \u003cL, R\u003e (right: R)\r\n```\r\n\r\n### left\r\n\r\nReturns an Either.Left with the given value.\r\n\r\n```js\r\nEither.left \u003cL, R\u003e (left: L)\r\n```\r\n\r\n### nothing\r\n\r\nReturns the Either.nothing singleton.\r\n\r\n```js\r\nEither.nothing (): Left\u003cvoid, void\u003e\r\n```\r\n\r\n### sequence\r\n\r\nConverts an array of Eithers into an Either of an array.\r\n\r\n```js\r\nEither.sequence \u003cL, R\u003e (...eithers: Array\u003cEither\u003cL, R\u003e\u003e): Either\u003cL, R[]\u003e\r\n```\r\n\r\n### traverse\r\n\r\nMaps an array into an Either of an array.\r\n\r\n```js\r\nEither.traverse \u003cL, R, S\u003e (f: (a: R) =\u003e Either\u003cL, S\u003e): (as: R[]) =\u003e Either\u003cL, S[]\u003e\r\n```\r\n\r\n### lift\r\n\r\n```js\r\nEither.lift \u003cError, T\u003e (partialFunction: (...args: any[]) =\u003e T): (...args: any[]) =\u003e Either\u003cError, T\u003e\r\n```\r\n\r\n\r\n### Instance Methods\r\n\r\n### isLeft\r\n\r\nReturns true if this is an Either.Left.\r\n\r\n```js\r\nisLeft (): boolean\r\n```\r\n\r\n### isRight\r\n\r\nReturns true if this is an Either.Right.\r\n\r\n```js\r\nisRight (): boolean\r\n```\r\n\r\n### get\r\n\r\nReturns the right value, or throws an error if Either.Left.\r\n\r\n```js\r\nget (): R | never;\r\n```\r\n\r\n## getRight\r\n\r\nReturns the right value, or throws an error if Either.Left.\r\n\r\n```js\r\ngetRight (): R | never\r\n```\r\n\r\n## getLeft\r\n\r\nReturns the left value, or throws an error if Either.Right.\r\n\r\n```js\r\ngetLeft (): L | never\r\n```\r\n\r\n### getOrElse\r\n\r\nReturns the right value or the result of the given function.\r\n\r\n```js\r\ngetOrElse (f: () =\u003e R): R\r\n```\r\n\r\n### getOrElseGet\r\n\r\nReturns the right value or the given value.\r\n\r\n```js\r\ngetOrElseGet (right: R): R\r\n```\r\n\r\n### getOrThrow\r\n\r\nReturns the right value or throws the given error.\r\n\r\n```js\r\ngetOrThrow (err?: Error): R | never\r\n```\r\n\r\n### orElse\r\n\r\nReturns the right value or the result of the given function.\r\n\r\n```js\r\norElse (f: () =\u003e Either\u003cL, R\u003e)\r\n```\r\n\r\n### map\r\n\r\nApplies the function to the value and wraps the result in another Either.\r\n\r\n```js\r\nmap \u003cS\u003e (f: (a: R) =\u003e S): Either\u003cL, S\u003e\r\n```\r\n\r\n### fmap\r\n\r\nApplies the function to the value and returns the result.\r\n\r\n```js\r\nfmap \u003cS\u003e (f: (a: R) =\u003e Either\u003cL, S\u003e): Either\u003cL, S\u003e\r\n```\r\n\r\n### applies\r\n\r\n```js\r\napplies \u003cS, T\u003e (f: ApplicativeFunc\u003cR, S, T\u003e): (mb: Either\u003cL, S\u003e) =\u003e Either\u003cL, T\u003e\r\n```\r\n\r\n###mbind\r\n\r\nBasically maps the right value to the Either.Right function.\r\n\r\n```js\r\nmbind \u003cS\u003e (f: Either\u003cL, (f: R) =\u003e Either\u003cL, S\u003e\u003e): Either\u003cL, S\u003e\r\n```\r\n\r\n### bimap\r\n\r\nApplies the applicable function to the value and produces an Either.\r\n\r\n```js\r\nbimap \u003cM, S\u003e (lf: (l: L) =\u003e M, rf: (r: R) =\u003e S): Either\u003cM, S\u003e\r\n```\r\n\r\n### cata\r\n\r\nApplies the applicable function to the Either and produces a value.\r\n\r\n```js\r\ncata \u003cV\u003e (lf: (l: L) =\u003e V, rf: (r: R) =\u003e V): V\r\n```\r\n\r\n### flatten\r\n\r\nFlattens an Either of nested Eithers to a one depth Either.\r\n\r\n```js\r\nflatten \u003cM, S\u003e (): Either \u003cM, S\u003e\r\n```\r\n\r\n### toMaybe\r\n\r\nConverts this Either to a Maybe.\r\n\r\n```js\r\ntoMaybe (): Maybe\u003cR\u003e\r\n```\r\n\r\n### toObject\r\n\r\nConverts the instance to a basic object.\r\n\r\n```js\r\ntoObject (): { left?: L; right?: R }\r\n```\r\n\r\n### toJSON\r\n\r\nAllows the instance to be converted to JSON.\r\n\r\n```js\r\ntoJSON (): { left?: L; right?: R }\r\n```\r\n\r\n### toString\r\n\r\nReturns the Either as a string: '{\"right\": R}' or '{\"left\": L}'\r\n\r\n```js\r\ntoString (): string\r\n```\r\n\r\n### equals\r\n\r\nTests the equality of the Eithers.\r\n\r\n```js\r\nequals (other: Either\u003cL, R\u003e): boolean\r\n```\r\n\r\n\r\n---\r\n\r\n## Tuples\r\n\r\nMonadness tuples are simply arrays with some extra methods.\r\n\r\n### Static Methods\r\n\r\n### Tuples.from\r\n\r\n```js\r\nTuples.from \u003cT1, ...Tn\u003e (_1: T1, ..._n: Tn): TupleN \u003cT1, ...Tn\u003e \u0026 [T1, ...Tn]\r\n```\r\n\r\n\r\n### Instance Getters\r\n\r\nAccesses the values of the tuple (not zero-based).\r\n\r\n```js\r\n_1: T1;\r\n_n: Tn;\r\n```\r\n\r\n\r\n### Instance Methods\r\n\r\nIn addition to all of the regular array methods, the Tuple class has the following methods.\r\n\r\n### map\r\n\r\nApplies the function to each value of the tuple.\r\n\r\n```js\r\nmap \u003cU1, ...Un\u003e (f: (a: T1 | ...Tn) =\u003e U1 | ...Un): Tuple9\u003cU1, ...Un\u003e\r\n```\r\n\r\n### fmap\r\n\r\nApplies the function to each value of the tuple.\r\n\r\n```js\r\nfmap \u003cU1, ...U9\u003e (f: (a: T1 | ...Tn) =\u003e Tuple1\u003cU1 | ...Un\u003e): Tuple9\u003cU1, ...Un\u003e\r\n```\r\n\r\n### applies\r\n\r\n```js\r\napplies \u003cU1, U2, ...Un, V1, ...Vn\u003e (f: ApplicativeFunc\u003cT1 | ...Tn, U1 | ...Un, V1 | ...Vn\u003e): (mb: Tuple9\u003cU1, ...Un\u003e) =\u003e Tuple9\u003cV1, ...Vn\u003e\r\n```\r\n\r\n### mbind\r\n\r\nApplies each function to each value respectively.\r\n\r\n```js\r\nmbind \u003cU1, ...Un\u003e (f: TupleN\u003cTMF\u003cT1, U1\u003e, ...TMF\u003cTn, Un\u003e\u003e): TupleN\u003cU1, ...Un\u003e\r\n```\r\n\r\n### toJSON\r\n\r\nConverts the tuple to a JSON object.\r\n\r\n```js\r\ntoJSON (): { just: T | null }\r\n```\r\n\r\n### equals\r\n\r\nTests the equality of two tuples.\r\n\r\n```js\r\nequals (other: TupleN\u003cT\u003e): boolean\r\n```\r\n\r\n\r\n**Example of Static Initializers and Usage:**\r\n\r\n```js\r\nimport { Tuples } from \"monadness\";\r\n\r\nconst tuple0 = Tuples.from();\r\nconst tuple1 = Tuples.from(\"a\");\r\nconst tuple2 = Tuples.from(\"a\", 2);\r\nconst tuple3 = Tuples.from(123, \"abc\", true);\r\nconst tuple4 = Tuples.from(1, 2, 3, 4);\r\nconst tuple5 = Tuples.from(1, 2, 3, 4, 5);\r\nconst tuple6 = Tuples.from(1, 2, 3, 4, 5, 6);\r\nconst tuple7 = Tuples.from(1, 2, 3, 4, 5, 6, 7);\r\nconst tuple8 = Tuples.from(1, 2, 3, 4, 5, 6, 7, 8);\r\nconst tuple9 = Tuples.from(1, 2, 3, 4, 5, 6, 7, 8, 9);\r\n\r\nconsole.log(\"First value:\", tuple2._1, tuple[0]);\r\nconsole.log(\"Second value:\", tuple2._2, tuple[1]);\r\n\r\nconst [x, y] = tuple2; // Desctructuring\r\n\r\nfor (const i in tuple4) {\r\n    console.log(\"Tuple4 values:\", tuple4[i]);\r\n}\r\n\r\nfor (const val of tuple5) {\r\n    console.log(\"Tuple5 values:\", val);\r\n}\r\n```\r\n\r\n\r\n---\r\n\r\n# License\r\n\r\n(The MIT License)\r\n\r\nCopyright (c) 2017 Patrick Martin\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and\r\nassociated documentation files (the 'Software'), to deal in the Software without restriction,\r\nincluding without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\nand/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\r\nsubject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial\r\nportions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT\r\nLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrimart%2Fmonadness-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatrimart%2Fmonadness-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrimart%2Fmonadness-js/lists"}