{"id":24594299,"url":"https://github.com/nilern/monnit","last_synced_at":"2025-07-14T08:04:56.170Z","repository":{"id":62431838,"uuid":"320058701","full_name":"nilern/monnit","owner":"nilern","description":"Monads, functors etc. for Clojure(Script)","archived":false,"fork":false,"pushed_at":"2021-03-10T17:51:07.000Z","size":82,"stargazers_count":19,"open_issues_count":4,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-01T16:10:58.901Z","etag":null,"topics":["category-theory","clojure","clojurescript","functor","monad"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nilern.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["nilern"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-12-09T19:28:33.000Z","updated_at":"2023-04-11T12:37:23.000Z","dependencies_parsed_at":"2022-11-01T21:01:02.809Z","dependency_job_id":null,"html_url":"https://github.com/nilern/monnit","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/nilern/monnit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2Fmonnit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2Fmonnit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2Fmonnit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2Fmonnit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nilern","download_url":"https://codeload.github.com/nilern/monnit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2Fmonnit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265262215,"owners_count":23736407,"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":["category-theory","clojure","clojurescript","functor","monad"],"created_at":"2025-01-24T11:14:18.675Z","updated_at":"2025-07-14T08:04:56.129Z","avatar_url":"https://github.com/nilern.png","language":"Clojure","funding_links":["https://github.com/sponsors/nilern"],"categories":[],"sub_categories":[],"readme":"# Monnit\n\n[![Clojars Project](https://img.shields.io/clojars/v/com.deepbeginnings/monnit.svg)](https://clojars.org/com.deepbeginnings/monnit)\n[![cljdoc badge](https://cljdoc.org/badge/com.deepbeginnings/monnit)](https://cljdoc.org/d/com.deepbeginnings/monnit/CURRENT)\n[![Build Status](https://img.shields.io/github/workflow/status/nilern/monnit/Run%20tests.svg)](https://github.com/nilern/monnit/actions)\n\nMonads, functors etc. for Clojure(Script).\n\n## Rationale (Why Yet Another Monads Library?)\n\nI was writing various other libraries (yet to be released) and most of the time\nthey ended up needing efficient Functor and Monad protocols. Having copies of\nthose protocols in every library is clearly silly. I did not want the extra\nindirection and magic of Cats (currying because of Applicative Functors,\n`MonadContext`s in dynamic Vars, monads that just wrap fns) or the loose typing\nof algo.monads (macros instead of protocols, the State monad is just a raw fn\ninstead of having a dedicated type).\n\nSo Monnit was born. Of course there are more monad libraries but they seem to\nhave a different focus (Fluokitten), be abandoned and to be honest, NIH.\n\n## Features\n\n* Functor, Monad etc. protocols and conveniences (e.g. a `do`-notation-like\n  `mlet` macro) in [monnit.core](https://cljdoc.org/d/com.deepbeginnings/monnit/CURRENT/api/monnit.core)\n* [monnit.option](https://cljdoc.org/d/com.deepbeginnings/monnit/CURRENT/api/monnit.option)\n  an alternative to `nil` and `NullPointerException`s\n* [monnit.result](https://cljdoc.org/d/com.deepbeginnings/monnit/CURRENT/api/monnit.result)\n  an alternative to `throw` and uncaught exceptions\n* [monnit.reader](https://cljdoc.org/d/com.deepbeginnings/monnit/CURRENT/api/monnit.reader)\n  hide the plumbing of an extra `ctx` parameter; also an alternative to dynamic Vars\n* [monnit.state](https://cljdoc.org/d/com.deepbeginnings/monnit/CURRENT/api/monnit.state)\n  hide the plumbing of an extra immutable accumulator/state value\n* [monnit.identity](https://cljdoc.org/d/com.deepbeginnings/monnit/CURRENT/api/monnit.identity)\n  the trivial Functor and Monad; occasionally useful, just like the identity function\n* [monnit.pair](https://cljdoc.org/d/com.deepbeginnings/monnit/CURRENT/api/monnit.pair)\n  a two-element tuple for the State monad and general use; less indirection than a `PersistentVector`\n\n## Performance\n\nA little State monad benchmark (in `/bench`) seems to support my performance\nintuitions:\n\n```\n$ clj -A:bench\nClojure 1.10.3\n\n\u003e (require '[monnit.benchmarks :as b])\nnil\n\n\u003e (b/benchmark-labeling 10)\n\n# clojure.core\nEvaluation count : 143400 in 60 samples of 2390 calls.\n             Execution time mean : 418,939803 µs\n    Execution time std-deviation : 645,276885 ns\n   Execution time lower quantile : 417,622749 µs ( 2,5%)\n   Execution time upper quantile : 419,771713 µs (97,5%)\n                   Overhead used : 2,266132 ns\n\nFound 1 outliers in 60 samples (1,6667 %)\n\tlow-severe\t 1 (1,6667 %)\n Variance from outliers : 1,6389 % Variance is slightly inflated by outliers\n\n# monnit.state\nEvaluation count : 153600 in 60 samples of 2560 calls.\n             Execution time mean : 391,324179 µs\n    Execution time std-deviation : 967,126577 ns\n   Execution time lower quantile : 390,299234 µs ( 2,5%)\n   Execution time upper quantile : 393,342059 µs (97,5%)\n                   Overhead used : 2,266132 ns\n\nFound 4 outliers in 60 samples (6,6667 %)\n\tlow-severe\t 1 (1,6667 %)\n\tlow-mild\t 1 (1,6667 %)\n\thigh-mild\t 2 (3,3333 %)\n Variance from outliers : 1,6389 % Variance is slightly inflated by outliers\n\n# clojure.algo.monads/state-m\nEvaluation count : 153600 in 60 samples of 2560 calls.\n             Execution time mean : 391,098502 µs\n    Execution time std-deviation : 346,384313 ns\n   Execution time lower quantile : 390,393749 µs ( 2,5%)\n   Execution time upper quantile : 391,640304 µs (97,5%)\n                   Overhead used : 2,266132 ns\n\n# cats.monad.state\nEvaluation count : 8580 in 60 samples of 143 calls.\n             Execution time mean : 7,025305 ms\n    Execution time std-deviation : 12,159509 µs\n   Execution time lower quantile : 7,002061 ms ( 2,5%)\n   Execution time upper quantile : 7,043491 ms (97,5%)\n                   Overhead used : 2,266132 ns\n```\n\nHere Monnit and algo.monads are about 7% faster than the vanilla Clojure\nversion, probably because the latter uses `PersistentVector`s and\ndestructuring. I was pleased to see that Monnit matches the performance of\nalgo.monads while keeping the State monad type (types, actually) distinct like\nCats.\n\nIn this benchmark the Cats State monad is about 17 times slower than the\nbaseline, probably due to the indirections mentioned earlier. To be fair, the\nState monad does not seem to be much of a priority for Cats; it was even\nremoved at some point, then re-added.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnilern%2Fmonnit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnilern%2Fmonnit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnilern%2Fmonnit/lists"}