{"id":23512761,"url":"https://github.com/baethon/phln","last_synced_at":"2025-04-19T12:17:47.192Z","repository":{"id":62491138,"uuid":"89615858","full_name":"baethon/phln","owner":"baethon","description":"Set of small utility functions. Inspired by Ramda 💜","archived":false,"fork":false,"pushed_at":"2020-09-27T20:55:24.000Z","size":1659,"stargazers_count":18,"open_issues_count":4,"forks_count":2,"subscribers_count":3,"default_branch":"3.x","last_synced_at":"2024-09-19T22:53:02.879Z","etag":null,"topics":["fp","function-php","functional-programming","php"],"latest_commit_sha":null,"homepage":"https://baethon.github.io/phln/","language":"PHP","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/baethon.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}},"created_at":"2017-04-27T16:02:55.000Z","updated_at":"2024-02-24T21:08:41.000Z","dependencies_parsed_at":"2022-11-02T09:31:40.611Z","dependency_job_id":null,"html_url":"https://github.com/baethon/phln","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fphln","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fphln/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fphln/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fphln/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baethon","download_url":"https://codeload.github.com/baethon/phln/tar.gz/refs/heads/3.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249692904,"owners_count":21311420,"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":["fp","function-php","functional-programming","php"],"created_at":"2024-12-25T13:19:22.943Z","updated_at":"2025-04-19T12:17:47.175Z","avatar_url":"https://github.com/baethon.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/baethon/phln.svg?branch=master)](https://travis-ci.org/baethon/phln) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/baethon/phln/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/baethon/phln/?branch=master)\n\n---\n\n# baethon/phln\n\nSet of small utility functions.\n\nHeavily inspired by [Ramda.js](http://ramdajs.com/), adapted for PHP needs.\n\n## Installation\n\n```bash\ncomposer require baethon/phln\n```\n\n## Example usage\n\n```php\nuse Baethon\\Phln\\Phln as P;\n\n$aboveMinPoints = P::compose(P::lte(50), P::prop('score'));\n$onlyPhp = P::pathEq('language.name', 'PHP');\n\n$topScores = collect($users)\n    -\u003efilter(P::both($aboveMinPoints, $onlyPhp));\n```\n\n_Note_: in the docs `P` will be used as an alias to `Baethon\\Phln\\Phln`.\n\n### Currying\n\n`Phln` methods are loosely curried. A `N-ary` method will return a function until all arguments are provided.\n\n```php\n$foo = P::curryN(2, function ($left, $right) {\n    return $left + $right;\n});\n\n$foo(1); // returns instance of \\Closure\n$foo(1, 2); // 3\n$foo(1)(2); // 3\n```\n\n### Partial application\n\nPartial application is possible with combination of `P::partial()` and `P::__` const. Partial returns a function which accepts arguments which should \"fill\" gap of missing arguments for callable.\n\n```php\n$foos = [1, 2, 3];\n$mapFoos = P::partial('\\\\array_map', [P::__, $foos]);\n$mapFoos(function ($f) {\n    return $f + 100;\n}); // [100, 200, 300]\n```\n\n### Function composition\n\nFor function composition `phln` provides `pipe()` and `compose()` functions.\n\n```php\n$allFoos = P::pipe(\n    P::filter(P::lte(5)),\n    P::map(P::always('foo'))\n);\n\n$firstFoo = P::compose(P::head(), $allFoos);\n\n$allFoos([4, 5, 6]); // ['foo', 'foo']\n$firstFoo([4, 5, 6]); // 'foo'\n```\n\n### Using methods as references\n\nSome of `phln` methods accept `callable` as an argument.\n\nTo pass another macro as a _reference_ call it without any arguments.\n\n```php\n$collection = [1, 2, 3, 4];\nP::reduce(P::sum(), $collection); // 10\n```\n\nAlso, you can use `P::raw()` method wich returns uncurried macro, or pointer to `Phln` method.\n\n### Extending\n\n`Baethon\\Phln\\Phln` is _macroable_. This means that it can be extened using `macro()` method:\n\n```php\nP::macro('foo', function () {\n    return 'foo';\n});\n\nP::foo(); // 'foo'\n```\n\n### Note about objects\n\nThe library takes terminology from Ramda. In most cases, it's perfectly fine, until one gets to the concept of _object_.\n\nRamda treats _objects_ as dictionaries. In JavaScript, there's only one type which can act as a dictionary. It's ... `object`.\n\nIn PHP things get complicated. It's possible to use arrays and objects as dictionaries. This way `Phln` has to treat both of those types as an _object_.\n\nFor compatibility reason, all functions which return _object_ will return `array`.\n\n## Testing\n\n```bash\n./vendor/bin/phpunit\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaethon%2Fphln","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaethon%2Fphln","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaethon%2Fphln/lists"}