{"id":18762112,"url":"https://github.com/druimalban/recursr","last_synced_at":"2026-04-18T14:04:44.435Z","repository":{"id":193126205,"uuid":"687995416","full_name":"druimalban/recursr","owner":"druimalban","description":"Generalised folds and unfolds for R","archived":false,"fork":false,"pushed_at":"2024-02-22T22:27:47.000Z","size":53,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"smile","last_synced_at":"2025-08-03T11:36:06.588Z","etag":null,"topics":["applied-data-science","category-theory","haskell","r","recursion","recursion-schemes"],"latest_commit_sha":null,"homepage":"https://druimalban.github.io","language":"R","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/druimalban.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","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":"2023-09-06T12:39:59.000Z","updated_at":"2023-12-13T20:56:26.000Z","dependencies_parsed_at":"2023-12-01T23:30:01.023Z","dependency_job_id":"d00a0df8-0258-4c6f-adad-b4629bf39276","html_url":"https://github.com/druimalban/recursr","commit_stats":null,"previous_names":["druimalban/recursr"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/druimalban/recursr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/druimalban%2Frecursr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/druimalban%2Frecursr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/druimalban%2Frecursr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/druimalban%2Frecursr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/druimalban","download_url":"https://codeload.github.com/druimalban/recursr/tar.gz/refs/heads/smile","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/druimalban%2Frecursr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31971500,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["applied-data-science","category-theory","haskell","r","recursion","recursion-schemes"],"created_at":"2024-11-07T18:19:26.697Z","updated_at":"2026-04-18T14:04:41.585Z","avatar_url":"https://github.com/druimalban.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"Full package documentation is [hosted on Github pages](https://druimalban.github.io/)!\n\n# Generalised folds and unfolds for R\n## Preface\n\nThis is an experiment in porting the Haskell\n[`recursion-schemes`](https://hackage.haskell.org/package/recursion-schemes)\npackage to R.\n\nThe library provides generalised folding and unfolding functions, which can be\napplied to a large number of data structures. The library provides just enough\nof the Haskell language infrastructure to make it possible to use the following\nhigher-order functions:\n\n  - The catamorphism and its categorical dual the anamorphism\n  - The paramorphism and its categorical dual the apomorphism\n  - The histomorphism and its categorical dual the futumorphism\n  \nRefolds like the hylomorphism are not implemented, but using building-blocks\nand the examples of the code provided, it should be feasible to\nimplement these.\n\n## Tutorial articles (vignettes) and package license\n\n[The first package vignette](https://druimalban.github.io/articles/list-morphisms.html) \nis a tutorial on making use of the various morphisms with the familiar list type. \nThis is primarily a demonstration of each function rather than an explanation of\nhow to implement a \"base\" functor for a given type.\n\n[The second package vignette](https://druimalban.github.io/articles/tree-morphisms.html)\nexplores implementation of fmap for the `data.tree` package's `Node` type,\nimplementation of a \"base\" functor for this type. \nBecause of that package's unpredictable behaviour, the vignette then explores\nimplementation of a basic `Tree` type. \nFinally, it explores implementation of a monad instance for the basic `Tree` \ntype, and testing it against the monad laws.\n\n[The third package vignette](https://druimalban.github.io/articles/fixed-point-programming.html)\nexplores using fixed-points instead of `project()`/`embed()`, \nand demonstrates this using Peano numbers.\nWhen I was building/testing the library, I used fixed-points instead of the \n`project()`/`embed()` functions, but I later replaced that code with those \nfunctions, and also adapted the \"base\" functor of a list to demonstrate the \npackage, so this library is to an extent adapted from the Haskell\n`recursion-schemes` package. It isn't clear to me what the implications are in\nterms of software licensing when adapting code/ideas (other libraries which \nimplement recursion-schemes such as SCALA's\n[`matryoshka`](https://github.com/precog/matryoshka/tree/master)\ndon't share the same license as `recursion-schemes`), so I've applied the same\nlicense (BSD 2-Clause) with a note of attribution. My own code is licensed under\nBSD 2-Clause.\n\n## Recursion schemes\n  \nMy initial explorations of catamorphisms and anamorphisms was largely inspired\nby the following, excellent, series of blog-posts: \nhttps://blog.ploeh.dk/2017/10/04/from-design-patterns-to-category-theory/\n(Seemann's book *Code that Fits in Your Head* also happens to be very good.)\n\nOther resources which are fairly accessible include the following:\n\n  - https://jtobin.io/practical-recursion-schemes (this is a series)\n  - https://blog.sumtypeofway.com/posts/introduction-to-recursion-schemes.html (this is a series)\n  - https://fho.f12n.de/posts/2014-05-07-dont-fear-the-cat.html\n  - https://arxiv.org/pdf/2202.13633.pdf\n\nI think that others are better able to explain the theory behind the various\nrecursion schemes in a more accurate and insightful manner than I can, so the\nfunction reference tends to be fairly sparse, although every function is\ndocumented, and the tutorial vignettes describe usage.\nSome of the terminology can also be confusing, and Haskell examples provided by\nothers tend to be more succint and clearer than my corresponding implementation\nin R. \n\n## Additional features implemented\n\nFutu and histo depend on the free monad and the cofree comonad, and para and apo\ndepend on the either monad and tuples. As such, the following language features\nare also implemented:\n\n  - S3 methods for functors (`fmap()`)\n  - S3 methods for monads (bind a.k.a. `\u003e\u003e=`, discard a.k.a. `\u003e\u003e`, and `join()`)\n  - S3 methods for comonads (`extract()`, `extend()`, and `duplicate()`)\n  - Infix pipes which work like the Haskell infix operators, surrounded by percentage signs similar to magrittr pipes\n  \nThus enabling the following:\n  \n  - The free monad and the cofree comonad\n  - An fmap and bind implementation for a list\n  - \"Base\" functor for a list, which represents the list functor at a given point in recursion\n  - The Either monad, as well as Tuple, with a fmap implementation for both and a bind implementation for Either. Not all tuples are monads.\n\nNote that Haskell has another typeclass, which bears mentioning, Applicative.\nIn fact, all monads are applicative functors. However, some Applicative \ninstances are pretty unintuitive, and there is invariably more than one possible\nApplicative instance, so I've not implemented Applicative for any of the types \nin this package.\n\n## Miscellaneous remarks\n\nPattern-matching—not supported in base R, and the various libraries do\nnot work like in Haskell—would have made many of my R functions much more\nsuccint.\n\nType signatures would have been helpful especially when implementing\nbuilding-blocks like fmap and free/cofree.\nIndeed, R is not strongly-typed—it will freely coerce values—but the S3 class\nsystem does at least enable writing functions which are specific to a given\nfunctor/monad, e.g. the bind implementation for Either only applies to Either\nvalues.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdruimalban%2Frecursr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdruimalban%2Frecursr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdruimalban%2Frecursr/lists"}