{"id":26227860,"url":"https://github.com/benji6/combinators-js","last_synced_at":"2025-04-04T13:03:58.637Z","repository":{"id":36319354,"uuid":"40624013","full_name":"benji6/combinators-js","owner":"benji6","description":":bird: Some combinators","archived":false,"fork":false,"pushed_at":"2024-12-03T21:17:11.000Z","size":277,"stargazers_count":136,"open_issues_count":3,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-28T12:08:06.696Z","etag":null,"topics":["combinator","combinatory-logic","functional-programming","haskell","lambda-calculus"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benji6.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-12T20:58:17.000Z","updated_at":"2025-03-25T07:21:58.000Z","dependencies_parsed_at":"2023-12-26T10:46:29.319Z","dependency_job_id":"eb33b577-fab6-48d2-bfc9-2d30bda488ea","html_url":"https://github.com/benji6/combinators-js","commit_stats":{"total_commits":98,"total_committers":6,"mean_commits":"16.333333333333332","dds":0.5,"last_synced_commit":"ade151a955e988b19377bd31e043a4460a039df7"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benji6%2Fcombinators-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benji6%2Fcombinators-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benji6%2Fcombinators-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benji6%2Fcombinators-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benji6","download_url":"https://codeload.github.com/benji6/combinators-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247182367,"owners_count":20897380,"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":["combinator","combinatory-logic","functional-programming","haskell","lambda-calculus"],"created_at":"2025-03-12T20:20:12.021Z","updated_at":"2025-04-04T13:03:58.616Z","avatar_url":"https://github.com/benji6.png","language":"JavaScript","readme":"# combinators-js\n\n[![npm version](https://badge.fury.io/js/combinators-js.svg)](http://badge.fury.io/js/combinators-js)\n[![Build Status](https://travis-ci.org/benji6/combinators-js.svg)](https://travis-ci.org/benji6/combinators-js)\n\n## Getting Started\n\nInstall (other package managers are available):\n\n```bash\nnpm i -S combinators-js\n```\n\nImport (other module systems are available):\n\n```javascript\nimport {\n  B, B1, B2, B3, C, C_, C__, D, D1, D2, E, F, F_, F__ G, H, I, I_, I__, J, K, L,\n  M, M2, O, Q, Q1, Q2, Q3, Q4, R, R_, R__, S, T, U, V, V_, V__, W, W_, W__, W1, Y,\n} from 'combinators-js'\n```\n\n## Definitions\n\nHere are the included combinators with their definitions:\n\n```javascript\nconst B = a =\u003e b =\u003e c =\u003e a(b(c))\nconst B1 = a =\u003e b =\u003e c =\u003e d =\u003e a(b(c)(d))\nconst B2 = a =\u003e b =\u003e c =\u003e d =\u003e e =\u003e a(b(c)(d)(e))\nconst B3 = a =\u003e b =\u003e c =\u003e d =\u003e a(b(c(d)))\nconst C = a =\u003e b =\u003e c =\u003e a(c)(b)\nconst C_ = a =\u003e b =\u003e c =\u003e d =\u003e a(b)(d)(c)\nconst C__ = a =\u003e b =\u003e c =\u003e d =\u003e e =\u003e a(b)(c)(e)(d)\nconst D = a =\u003e b =\u003e c =\u003e d =\u003e a(b)(c(d))\nconst D1 = a =\u003e b =\u003e c =\u003e d =\u003e e =\u003e a(b)(c)(d(e))\nconst D2 = a =\u003e b =\u003e c =\u003e d =\u003e e =\u003e a(b(c))(d(e))\nconst E = a =\u003e b =\u003e c =\u003e d =\u003e e =\u003e a(b)(c(d)(e))\nconst F = a =\u003e b =\u003e c =\u003e c(b)(a)\nconst F_ = a =\u003e b =\u003e c =\u003e d =\u003e a(d)(c)(b)\nconst F__ = a =\u003e b =\u003e c =\u003e d =\u003e e =\u003e a(b)(e)(d)(c)\nconst G = a =\u003e b =\u003e c =\u003e d =\u003e a(d)(b(c))\nconst H = a =\u003e b =\u003e c =\u003e a(b)(c)(b)\nconst I = a =\u003e a\nconst I_ = a =\u003e b =\u003e a(b)\nconst I__ = a =\u003e b =\u003e c =\u003e a(b)(c)\nconst J = a =\u003e b =\u003e c =\u003e d =\u003e a(b)(a(d)(c))\nconst K = a =\u003e b =\u003e a\nconst L = a =\u003e b =\u003e a(b(b))\nconst M = a =\u003e a(a)\nconst M2 = a =\u003e b =\u003e a(b)(a(b))\nconst O = a =\u003e b =\u003e b(a(b))\nconst Q = a =\u003e b =\u003e c =\u003e b(a(c))\nconst Q1 = a =\u003e b =\u003e c =\u003e a(c(b))\nconst Q2 = a =\u003e b =\u003e c =\u003e b(c(a))\nconst Q3 = a =\u003e b =\u003e c =\u003e c(a(b))\nconst Q4 = a =\u003e b =\u003e c =\u003e c(b(a))\nconst R = a =\u003e b =\u003e c =\u003e b(c)(a)\nconst R_ = a =\u003e b =\u003e c =\u003e d =\u003e a(c)(d)(b)\nconst R__ = a =\u003e b =\u003e c =\u003e d =\u003e e =\u003e a(b)(d)(e)(c)\nconst S = a =\u003e b =\u003e c =\u003e a(c)(b(c))\nconst T = a =\u003e b =\u003e b(a)\nconst U = a =\u003e b =\u003e b(a(a)(b))\nconst V = a =\u003e b =\u003e c =\u003e c(a)(b)\nconst V_ = a =\u003e b =\u003e c =\u003e d =\u003e a(c)(b)(d)\nconst V__ = a =\u003e b =\u003e c =\u003e d =\u003e e =\u003e a(b)(e)(c)(d)\nconst W = a =\u003e b =\u003e a(b)(b)\nconst W_ = a =\u003e b =\u003e c =\u003e a(b)(c)(c)\nconst W__ = a =\u003e b =\u003e c =\u003e d =\u003e a(b)(c)(d)(d)\nconst W1 = a =\u003e b =\u003e b(a)(a)\nconst Y = a =\u003e (b =\u003e b(b))(b =\u003e a(c =\u003e b(b)(c)))\n```\n\n## Tests\n\n```javascript\ntest('B')(S(K(S))(K))\ntest('B1')(S(K(S(K(S))(K)))(S(K(S))(K)))\ntest('B2')(S(K(S(K(S(K(S))(K)))(S(K(S))(K))))(S(K(S))(K)))\ntest('C')(S(S(K(S(K(S))(K)))(S))(K(K)))\ntest('C_')(S(K(S(S(K(S(K(S))(K)))(S))(K(K)))))\ntest('C__')(S(K(S(K(S(S(K(S(K(S))(K)))(S))(K(K)))))))\ntest('D')(S(K(S(K(S))(K))))\ntest('D1')(S(K(S(K(S(K(S))(K))))))\ntest('D2')(S(K(S(K(S))(K)))(S(K(S(K(S))(K)))))\ntest('E')(S(K(S(K(S(K(S))(K)))(S(K(S))(K)))))\ntest('F')(S(K(S(S(K)(K))(K(S(K(S(S(K)(K))))(K)))))(S(K(S(K(S(K(S))(K)))(S(K(S))(K))))(S(K(S(S(K)(K))))(K))))\ntest('F_')(S(K(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K)))))))\ntest('F__')(S(K(S(K(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K)))))))))\ntest('G')(S(K(S(K(S))(K)))(S(S(K(S(K(S))(K)))(S))(K(K))))\ntest('H')(S(K(S(K(S(S(K(S(S(K)(K))(S(K)(K))))(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K))))))(K)))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))))\ntest('I')(S(K)(K))\ntest('I_')(S(S(K)))\ntest('J')(S(K(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))))(S(S(K(S(S(K)(K))(S(K)(K))))(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K))))(K(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(K(S(K(S))(K)))(S(K(S))(K)))))))))\ntest('K')(K)\ntest('L')(S(S(K(S))(K))(K(S(S(K)(K))(S(K)(K)))))\ntest('M')(S(S(K)(K))(S(K)(K)))\ntest('M2')(S(K(S(S(K)(K))(S(K)(K)))))\ntest('O')(S(S(K)(K)))\ntest('Q')(S(K(S(S(K(S))(K))))(K))\ntest('Q1')(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S))(K)))\ntest('Q2')(S(K(S(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S))(K)))))(K))\ntest('Q3')(S(K(S(K(S(S(K)(K))))(K))))\ntest('Q4')(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S))(K)))))(K)))\ntest('R')(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K)))\ntest('R_')(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))))\ntest('R__')(S(K(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))))))\ntest('S')(S)\ntest('T')(S(K(S(S(K)(K))))(K))\ntest('U')(S(K(S(S(K)(K))))(S(S(K)(K))(S(K)(K))))\ntest('V')(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K)(K))))(K)))\ntest('V_')(S(K(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))))))))\ntest('W')(S(K(S(S(K(S(S(K)(K))(S(K)(K))))(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K))))))(K))\ntest('W_')(S(K(S(K(S(S(K(S(S(K)(K))(S(K)(K))))(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K))))))(K))))\ntest('W__')(S(K(S(K(S(K(S(S(K(S(S(K)(K))(S(K)(K))))(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K))))))(K))))))\ntest('W1')(S(K(S(S(K(S(S(K(S(S(K)(K))(S(K)(K))))(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K))))))(K))))(K))\n```\n\n## Ideas\n\n```javascript\n// LISP data structures\nconst KI = K(I)\nconst cons = (a, b) =\u003e V(a)(b) // manual uncurry\nconst car = T(K)\nconst cdr = T(KI)\n\nconsole.log(car(cons(0, 1))) // =\u003e 0\nconsole.log(cdr(cons(0, 1))) // =\u003e 1\n\nconst nil = () =\u003e {}\nconst list = (...args) =\u003e args.reduce((l, arg) =\u003e V(arg)(l), nil)\nconst reverse = (l, m = nil) =\u003e l === nil ? m : reverse(l(KI), V(l(K))(m))\nconst reduce = f =\u003e l =\u003e m =\u003e l(KI) === undefined ? m : f(reduce(f)(l(KI))(m))(l(K))\nconst map = f =\u003e l =\u003e reduce(acc =\u003e val =\u003e V(f(val))(acc))(l)(nil)\nconst length = l =\u003e reduce(acc =\u003e val =\u003e 1 + acc)(l)(0)\nconst filter = f =\u003e l =\u003e reduce(acc =\u003e val =\u003e f(val) ? V(val)(acc) : acc)(l)(nil)\n\nconst arbitraryList = list(0, 1, 2, 3, 4, 5)\n\nconsole.log(length(arbitraryList)) // =\u003e 6\n\nconst reduced = reduce(acc =\u003e val =\u003e V(val)(acc))(arbitraryList)(nil)\nconst filtered = filter(x =\u003e x \u003e 2)(reduced)\nconst mapped = map(x =\u003e x ** 2)(filtered)\nconst reversed = reverse(mapped)\n\nconsole.log(length(reversed)) // =\u003e 3\nmap(::console.log)(reversed) // =\u003e 25 16 9\n```\n\n```javascript\n// recursion of anonymous functions\nY(recur =\u003e x =\u003e x === 1 ? 1 : x * recur(x - 1))(5) // =\u003e 120\n\n// TCO'd recursion of anonymous functions using a modified Y\n// taking a variadic non-combinator function\nconst Y_ = a =\u003e (b =\u003e a((...c) =\u003e b(b)(...c)))(b =\u003e a((...c) =\u003e b(b)(...c)))\nY_(recur =\u003e (x, y = 1) =\u003e x === 1 ? y : recur(x - 1, x * y))(5) // =\u003e 120\n```\n\n```javascript\n// omega bird (mock a mockingbird)\nM(M)\n```\n\n## Practical Ideas\n\n```\n¯\\_(ツ)_/¯\n```\n\n## See Also\n\nI built a [Church encoding library](https://github.com/benji6/church) too.\n\n## Further Reading\n\n- [To Mock a Mockingbird](https://en.wikipedia.org/wiki/To_Mock_a_Mockingbird)\n- [http://www.angelfire.com/tx4/cus/combinator/birds.html](http://www.angelfire.com/tx4/cus/combinator/birds.html)\n- [https://github.com/raganwald/oscin.es](https://github.com/raganwald/oscin.es)\n- [http://raganwald.com/2015/02/13/functional-quantum-electrodynamics.html](http://raganwald.com/2015/02/13/functional-quantum-electrodynamics.html)\n- [http://dkeenan.com/Lambda/](http://dkeenan.com/Lambda/)\n","funding_links":[],"categories":["Javascript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenji6%2Fcombinators-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenji6%2Fcombinators-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenji6%2Fcombinators-js/lists"}