{"id":45212354,"url":"https://github.com/oaxoa/fp-booleans","last_synced_at":"2026-02-20T16:36:16.824Z","repository":{"id":211621083,"uuid":"729583586","full_name":"Oaxoa/fp-booleans","owner":"Oaxoa","description":"A collection of utility functions to apply boolean logic on functions (including higher-order).  Written (and can be used) in a functional programming style.","archived":false,"fork":false,"pushed_at":"2024-11-11T08:17:54.000Z","size":1076,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-27T01:54:11.259Z","etag":null,"topics":["boolean","boolean-functions","boolean-logic","boolean-operations"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/Oaxoa.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2023-12-09T17:30:47.000Z","updated_at":"2025-09-05T20:51:05.000Z","dependencies_parsed_at":"2024-01-15T00:18:18.722Z","dependency_job_id":"ab39cb54-f2f6-48d2-a6cd-8c82d2a454bb","html_url":"https://github.com/Oaxoa/fp-booleans","commit_stats":null,"previous_names":["oaxoa/fp-booleans"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Oaxoa/fp-booleans","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oaxoa%2Ffp-booleans","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oaxoa%2Ffp-booleans/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oaxoa%2Ffp-booleans/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oaxoa%2Ffp-booleans/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Oaxoa","download_url":"https://codeload.github.com/Oaxoa/fp-booleans/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oaxoa%2Ffp-booleans/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29657083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T16:33:43.953Z","status":"ssl_error","status_checked_at":"2026-02-20T16:33:43.598Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["boolean","boolean-functions","boolean-logic","boolean-operations"],"created_at":"2026-02-20T16:36:16.083Z","updated_at":"2026-02-20T16:36:16.819Z","avatar_url":"https://github.com/Oaxoa.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"./assets/logo.png\" alt=\"\" width=\"200\" /\u003e\u003cbr\u003e\n\u003cp\u003e\u003cimg src=\"https://github.com/oaxoa/fp-booleans/actions/workflows/build.yml/badge.svg\" alt=\"\" /\u003e\u003c/p\u003e\n\n# fp-booleans\n\nA collection of utility functions to apply boolean logic **on functions** (including higher-order).\n\nWritten (and can be used) in a functional programming style.\n\n\u003e _fp-booleans_ functions are:\n\u003e\n\u003e 1. Small\n\u003e 1. Pure\n\u003e 1. Zero-dependencies\n\u003e 1. Tree-shakeable\n\u003e 1. Fully tested by design\n\n## Functions\n\n1. `not()`\n2. `and()`\n3. `or()`\n\n### Why\n\nBeing able to combine or negate booleans, predicate functions and higher-order predicate functions means lots of\n💪 power.\u003cbr\u003e\nWith a flexible yet simple API and TS annotations this can be easy too.\n\n### Examples\n\n#### `not()`\n\nUnary function: accepts boolean, predicate, higher-order predicate.\n\n##### On predicates\n\nWe can use `not()` on a predicate function to \"reverse\" it and get\na function with the same signature but opposite logic\n\n```js\nconst notGreaterThan100 = not(greaterThan100);\nconst fail = notGreaterThan100(score);\n// same as\nconst fail = not(greaterThan100)(score)\n```\n\n##### On a higher order functions\n\nThe best part is we can also use it on a higher-order function that returns a predicate:\n\n```js\nconst greaterThan = (comparison: number) =\u003e (arg: number) =\u003e arg \u003e comparison;\n\n// we now have several options:\n\n// we could just reverse the boolean value\nconst fail = not(greaterThan(100)(score))\n// or the predicate (which is a partially-applied HoF)\nconst fail = not(greaterThan(100))(score);\n// or reverse the higher-order function itself\nconst fail = not(greaterThan)(100)(score);\n```\n\n\u003e [!TIP]\n\u003e Being able to move parenthesis around is not for the sake of 🤹 juggling code.\u003cbr\u003e\u003cbr\u003e\n\u003e This flexibility allows to have the complexity (and unit tests) in one single function, _partially apply_ it as much\n\u003e as needed and then applying boolean operations on the specialized function without the need of writing several similar\n\u003e functions (and testing them, as the partial application is declarative in nature).\u003cbr\u003e\u003cbr\u003eImagine if instead than a\n\u003e simple `score \u003e 100` logic in our examples we had a\n\u003e complex function\u0026hellip; \u003cbr\u003eNegating it or combining it could require writing several slightly different versions\n\u003e of the logic (that should all be\n\u003e unit tested). With `not()` we can avoid this duplication.\n\n##### On boolean values (or expressions)\n\nThis is the simplest use case:\nImagine we want to pass or fail a level in a game based on the score being greater than 100:\n\n```js\nconst greaterThan100 = (n: number) =\u003e n \u003e 100;\nconst pass = greaterThan100(score);\nconst fail = !pass;\n```\n\nThe `!` only works on the boolean value (or equivalent expression), not on the function reference.\n\nIn this case we could use `not()` to just reverse the boolean value or expression.\n(nothing fancy here, just equivalent to `!`)\n\n```js\nconst fail = not(pass);\n```\n\nbut `not()` can also be used as mapper:\n\n```js\nconst flippedValues = [true, false].map(not); // [false, true]\n```\n\n```ts\nconst flippedValues = [true, false].map(not as (value: boolean) =\u003e boolean); // [false, true]\n```\n\n#### `and()`\n\nN-ary function.\n\nCombining functions is a foundation of functional programming.\n\nImagine again some code where we are granting a special bonus score based on some logic:\n\n```js\nconst isBonusScore = score =\u003e score % 2 === 0 \u0026\u0026 score \u003e 0 \u0026\u0026 score \u003c= 100;\n```\n\nThis code, while still being simple, is hard to read, to test and maintain.\nThis kind of code tends to be infused with business logic and be rewritten with mild differences in several places.\nCombining simpler functions would help almost not writing code and ease readability using a declarative syntax.\n\nThe first step would be to isolate the logic into simpler functions:\n\n```js\nconst isEven = n =\u003e n % 2 === 0;\nconst isGreaterThan = compare =\u003e n =\u003e n \u003e compare;\nconst isBetween = (min, max) =\u003e isGreaterThan(min) \u0026\u0026 not(isGreaterThan(max));\n```\n\n\u003e [!NOTE]\n\u003e This is a one-time job (or no job at all if you already have them or use some external package) and once tested these\n\u003e functions are going to be\n\u003e bullet-proof.\n\nWith these _utils_ in place, we could create one function that combines expressions (booleans) with the `\u0026\u0026` operator,\nbut it would require to\nhave a function signature, invoke all functions, and passing the same parameter and would look like:\n\n```js\nconst isBonusScore = score =\u003e isEven(score) \u0026\u0026 isBetween(0, 100)(score);\n```\n\nInstead, we could just `and()` (combine the function references) and go point-free.\n\n```js\nconst isBonusScore = and(isEven, isBetween(0, 100));\nisBonusScore(50); // true\n```\n\nSee how combining functions references is more compact than combining expressions in a function?\n\n#### `or()`\n\nWhat just described about the `and()` function applies to `or()`. E.g.:\n\n```js\nconst isValid = or(isNegative, isGreaterThan(100));\n```\n\n#### All together\n\n_fp-booleans_ functions can be all combined to unleash infinite 🚀 power:\n\n```js\nnot(is(5));\nnot(is)(5);\nand(greaterThanOrEqual(MIN_PRICE), not(isRound));\nor(is('admin'), and(startsWith('user_'), isLowerCase));\n```\n\n#### Used in filters\n\nCan be used in filters:\n\n```js\narray.filter(not(is(5)));\narray.filter(and(\n    greaterThanOrEqual(MIN_PRICE),\n    not(isRound))\n);\narray.filter(or(\n        is('admin'),\n        and(\n            startsWith('user_'),\n            isLowerCase)\n    )\n);\n```\n\n\u003e [!TIP]\n\u003e \u003cimg src=\"https://github.com/Oaxoa/fp-filters/raw/master/assets/logo.png\" alt=\"\" width=\"50\" /\u003e\n\u003e _fp-booleans_ is used at the core of [fp-filters](https://github.com/Oaxoa/fp-filters), a curated list of filter\n\u003e functions. Check it, and you may never have to write another filter function 🚀!\n\n### Additional Exports\n\nTwo more utils functions are exported:\n\n1. `isPredicate`\n1. `isHigherOrderPredicate`\n\nthey can check if a function is a predicate (returns boolean) or is a higher-order predicate (a function that when\ninvoked returns a predicate).\n\n#### Examples\n\n```ts\nisPredicate(someFunction);\nisHigherOrderPredicate(someFunction);\n```\n\n## Getting started\n\n### Installation\n\n_fp-booleans_ runs on Node.js and is available as a NPM package.\n\n```bash\nnpm install --save fp-booleans\n```\n\nor\n\n```bash\nyarn add fp-booleans\n```\n\n## License\n\n[MIT](https://opensource.org/licenses/MIT)\n\nCopyright (c) 2023-present, Pierluigi Pesenti","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foaxoa%2Ffp-booleans","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foaxoa%2Ffp-booleans","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foaxoa%2Ffp-booleans/lists"}