{"id":20090940,"url":"https://github.com/raehik/rerefined","last_synced_at":"2025-05-06T03:30:54.329Z","repository":{"id":235853294,"uuid":"791391007","full_name":"raehik/rerefined","owner":"raehik","description":"Refinement types in Haskell, again","archived":false,"fork":false,"pushed_at":"2024-10-24T17:28:13.000Z","size":89,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-16T21:47:01.816Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","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/raehik.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-24T16:26:24.000Z","updated_at":"2025-03-19T12:32:11.000Z","dependencies_parsed_at":"2024-04-24T19:10:46.302Z","dependency_job_id":"069028fa-7ad6-4a7a-b2e6-25d5c58da295","html_url":"https://github.com/raehik/rerefined","commit_stats":null,"previous_names":["raehik/rerefined"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raehik%2Frerefined","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raehik%2Frerefined/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raehik%2Frerefined/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raehik%2Frerefined/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raehik","download_url":"https://codeload.github.com/raehik/rerefined/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252616106,"owners_count":21776920,"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-13T16:27:29.147Z","updated_at":"2025-05-06T03:30:54.059Z","avatar_url":"https://github.com/raehik.png","language":"Haskell","readme":"# rerefined\n[refined-nv-gh]:      https://github.com/nikita-volkov/refined\n[refined-nv-hackage]: https://hackage.haskell.org/package/refined\n[strongweak-hackage]: https://hackage.haskell.org/package/strongweak\n[binrep-hackage]:     https://hackage.haskell.org/package/binrep\n[refined1-hackage]:   https://hackage.haskell.org/package/refined1\n\nRewrite of Nikita Volkov's [refined][refined-nv-hackage] library.\n\n* same concept\n* same performance\n* more predicates (signed value comparisons)\n* more features (functor predicates, predicate simplification)\n* better ergonomics (no insidious `Typeable` constraints)\n* neater internals: fewer dependencies (no `aeson`), better errors, more concise\n\n## Why?\nI used the original [refined][refined-nv-hackage] library fairly extensively to\npower other libraries (see [strongweak][strongweak-hackage],\n[binrep][binrep-hackage]), though I moved to a fork [refined1][refined1-hackage]\nsome time ago to provide a feature I needed. I think the library has some flaws\nand I want to contribute, but my tiny tweaks are still pending after a few\nyears. A good excuse to rewrite from the ground up.\n\nAll source code is original.\n\n### Why not merge into refined?\nrerefined is a complete modern rewrite. As such, it works plenty differently,\nand doesn't support older GHCs.\n\nI do want to add missing features into refined, such as functor predicates. But\nrefined is receiving minimal maintenance recently (2022-2024), and my changesets\nare languishing.\n\n## Differences from original refined\n### New features\n#### `Refined1` for functor predicates\n[refined-gh-refined1]: https://github.com/nikita-volkov/refined/pull/99\n\nSome predicates operate on the `f` of an `f a`. In such cases, given an\n`Refined1 (f a) :: Refined1 p f a`, we should be permitted to make changes\ninside the functor, that do not change the functor structure/shape. These are\nprovided by the `Functor` and `Traversable` instances on `Refined1`.\n\nDraft PR for refined at [refined#99][refined-gh-refined1].\n\n#### Type-level refinement simplification\nA primitive predicate simplifier is provided at `Rerefined.Simplify`. It can\nsimplify immediate cases of identity laws and so on.\n\n#### Infix operator-style predicate definitions\n`Rerefined.Predicate.Operators` exports type synonyms for writing predicates\nusing infix operators. (refined provides a handful, but they coincide with\nexisting operators, such as `\u0026\u0026`.)\n\n### Changes\n#### Simplified errors\nrefined encoded the logical predicates in its error type. This doesn't enable\nany further analysis, just turns a non-sum type into a sum type and complicates\nconsumption. Furthermore, this error type is first transformed into another\nrecursive ADT, which is only then pretty printed. This is unnecessary (even\nmentioned in the code).\n\nrerefined has a single-constructor error type which can be easily and\nefficiently turned into a string-like in a single pass.\n\n#### No insidious `Typeable` contexts\n[hackage-tls]: https://hackage.haskell.org/package/type-level-show\n\nSee [refined#101](https://github.com/nikita-volkov/refined/issues/101).\n`Typeable` is useful, but the way it is used brings lots of `Typeable` contexts.\n\nrerefined asks that you do a bit more work upfront, but gives you tools and\ngrants much more power. Predicates now must declare a \"name\":\n\n```haskell\nclass Predicate p where type PredicateName (d :: Natural) p :: Symbol\n```\n\nPrecedence is supported to permit writing names as infix operators. (For now,\nthe logical operators primarily look like their propositional logic\ncounterparts.) The [type-level-show][hackage-tls] package provides utilities for\nprinting `Natural`s and handling precedence.\n\n#### More re-use\nWhat do `LessThan`, `GreaterThan`, `EqualTo` etc. have in common? They're all\nrelational binary operators where one value is a pre-filled `Natural`. rerefined\npacks all of these into a single predicate that takes a type-level relational\noperator. Only one instance for the same amount of code, and much easier to\nreason about.\n\nWe take this even further and allow passing a type-level sign, to enable\ncomparing negative values.\n\nWe take this _even_ further and use the same relational operator definitions to\ndefine length comparisons, where the other value is taken from the input's\nlength (rather than its numeric value). This does not take a sign, since length\nmust be non-negative.\n\n#### More instances\nYou know that length comparison predicate above? It has a _single instance_ for\neach of `Refined1` and `Refined`:\n\n```haskell\n-- | Compare the length of a 'Foldable' to a type-level 'Natural' using the\n--   given 'RelOp'.\ninstance (KnownNat n, Foldable f, ReifyRelOp op)\n  =\u003e Refine1 (CompareLength op n) f where\n    validate1 p = validateCompareLength p . length\n\n-- | Compare the length of a 'MonoFoldable' to a type-level 'Natural' using the\n--   given 'RelOp'.\ninstance (KnownNat n, MonoFoldable a, ReifyRelOp op)\n  =\u003e Refine (CompareLength op n) a where\n    validate p = validateCompareLength p . olength\n```\n\nWe get a ton more instances for a ton less code. (Note that mono-foldable has a\nsurprisingly small footprint, as most of its transitive dependencies are core\nlibraries.)\n\n### Other\n* much cleaner module organization\n  * predicates defined in standalone modules; only import what you need\n* `Rerefined.Predicate.Via.validateVia` for defining predicates that are\n  implemented by an existing predicate\n* more logical predicates (NAND, if, if-and-only-if)\n\n## License\nProvided under the MIT license. See `LICENSE` for license text.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraehik%2Frerefined","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraehik%2Frerefined","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraehik%2Frerefined/lists"}