{"id":19585404,"url":"https://github.com/russellmcc/fantasydo","last_synced_at":"2025-07-19T12:34:48.805Z","repository":{"id":13346648,"uuid":"16033848","full_name":"russellmcc/fantasydo","owner":"russellmcc","description":"Do-notation for javascript fantasy land","archived":false,"fork":false,"pushed_at":"2014-01-18T21:01:02.000Z","size":124,"stargazers_count":64,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-23T03:48:12.416Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/russellmcc.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":"2014-01-18T20:56:58.000Z","updated_at":"2024-11-14T03:08:51.000Z","dependencies_parsed_at":"2022-09-04T10:51:34.528Z","dependency_job_id":null,"html_url":"https://github.com/russellmcc/fantasydo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/russellmcc/fantasydo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russellmcc%2Ffantasydo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russellmcc%2Ffantasydo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russellmcc%2Ffantasydo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russellmcc%2Ffantasydo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/russellmcc","download_url":"https://codeload.github.com/russellmcc/fantasydo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/russellmcc%2Ffantasydo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265934240,"owners_count":23852089,"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":[],"created_at":"2024-11-11T07:54:02.582Z","updated_at":"2025-07-19T12:34:48.722Z","avatar_url":"https://github.com/russellmcc.png","language":"JavaScript","readme":"# Fantasy Do\n\nFantasy do is a generalization of mozilla's [`task.js`](http://taskjs.org/) from [Promises/A+](http://promises-aplus.github.io/promises-spec/) to any monad, as defined by the [Fantasy Land Spec](https://raw.github.com/fantasyland/fantasy-land/).  While usage is syntactically similar to Haskell's Do Notation, it's implemented completely at runtime with [ES6 generators](http://wiki.ecmascript.org/doku.php?id=harmony:generators).  \n\n![Fantasy Land Branding](https://raw.github.com/fantasyland/fantasy-land/master/logo.png)\n\n## Usage\n\nFantasy Do requires ES6 generators.  In node, you can enable these with the `--harmony` option.\n\nIf you happen to have a browser with ES6 support, use the included `fantasydo.min.js` with your [module loader of choice](https://github.com/forbeslindesay/umd), or just with a `script` tag.\n\nThe library is available for `node.js` on `npm` under `fantasydo`\n\n### Normal mode\n\nIf your monad only calls the argument to the `chain` function once ('non-branching'), you can use Fantasy Do's normal, high-performance mode.\n\nFirst, you'll need a monad.  See the [Fantasy Land Implementation List](https://github.com/fantasyland/fantasy-land/blob/master/implementations.md) to find some monads that may work for you.\n\nHere's a very simple `Maybe` monad:\n\t\n\tvar Maybe = {}\n\tMaybe.chain = function(f) {\n\t    if(this.val !== null)\n\t        return f(this.val);\n\t    return this;\n\t};\n\tMaybe.of = function(t) {\n\t    return {\"val\" : t, \"chain\" : Maybe.chain};\n\t};\n\tMaybe.none = function() {\n\t    return {\"val\" : null, \"chain\" : Maybe.chain};\n\t};\n\nNow, we can write a function that depends on multiple maybe values, and will only complete if all of them are not `none`:\n\n\tDo(function*(){\n\t    var a = yield Maybe.of(7);\n\t    var b = yield Maybe.of(a + 9);\n\t    return b;\n\t }, Maybe).val; // =\u003e 16\n\n    Do(function*(){\n        var a = yield Maybe.of(7);\n        var q = yield Maybe.none();\n        var b = yield Maybe.of(a + 9);\n        return b;\n    }, Maybe).val;  // =\u003e null\n\n### Multi-mode\n\nFantasy Do also supports monads that may call their `chain` parameter multiple times, like the non-determinism context (aka the list monad).  Without the ability to copy generator state, this works by re-runninng the generator from the beginning for each branch.  This may behave strangely if your bind argument has significant side-effects.\n\n    Array.prototype.chain = function(f) {\n      let next = [];\n      let len = this.length;\n      this.forEach(function(it){\n          let v = f(it);\n          v.forEach(function(it){next.push(it)});\n      });\n      return next;\n    };\n\tArray.prototype.of = function(t) {return [t];}\n\nthen,\n\n    Do.Multi(function*(){\n        let c = yield [1, 2];\n        let d = yield [c + 1, c + 2];\n        return d;\n    }, Array.prototype); // =\u003e [2, 3, 3, 4]\n\n## License\n\n\u003cp xmlns:dct=\"http://purl.org/dc/terms/\" xmlns:vcard=\"http://www.w3.org/2001/vcard-rdf/3.0#\"\u003e\n  \u003ca rel=\"license\"\n     href=\"http://creativecommons.org/publicdomain/zero/1.0/\"\u003e\n    \u003cimg src=\"http://i.creativecommons.org/p/zero/1.0/80x15.png\" style=\"border-style: none;\" alt=\"CC0\" /\u003e\n  \u003c/a\u003e\n  \u003cbr /\u003e\n  To the extent possible under law,\n  \u003ca rel=\"dct:publisher\"\n     href=\"russellmcc.com\"\u003e\n    \u003cspan property=\"dct:title\"\u003eRussell McClellan\u003c/span\u003e\u003c/a\u003e\n  has waived all copyright and related or neighboring rights to\n  \u003cspan property=\"dct:title\"\u003eFantasy Do\u003c/span\u003e.\nThis work is published from:\n\u003cspan property=\"vcard:Country\" datatype=\"dct:ISO3166\"\n      content=\"US\" about=\"russellmcc.com\"\u003e\n  United States\u003c/span\u003e.\n\u003c/p\u003e","funding_links":[],"categories":["Libraries"],"sub_categories":["[Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frussellmcc%2Ffantasydo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frussellmcc%2Ffantasydo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frussellmcc%2Ffantasydo/lists"}