{"id":31588649,"url":"https://github.com/bardoor/monaditto","last_synced_at":"2026-03-08T08:33:28.352Z","repository":{"id":309990011,"uuid":"1038300913","full_name":"bardoor/monaditto","owner":"bardoor","description":"A pragmatic monad library for Elixir, no PhD required","archived":false,"fork":false,"pushed_at":"2025-09-04T10:24:18.000Z","size":66,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-01T13:45:57.600Z","etag":null,"topics":["elixir","functional-programming","monad"],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/bardoor.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,"zenodo":null}},"created_at":"2025-08-15T00:33:42.000Z","updated_at":"2025-09-04T10:24:21.000Z","dependencies_parsed_at":"2025-08-15T02:27:20.286Z","dependency_job_id":"976918a1-4aed-404d-a3cb-d491d996680b","html_url":"https://github.com/bardoor/monaditto","commit_stats":null,"previous_names":["bardoor/monaditto"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/bardoor/monaditto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bardoor%2Fmonaditto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bardoor%2Fmonaditto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bardoor%2Fmonaditto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bardoor%2Fmonaditto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bardoor","download_url":"https://codeload.github.com/bardoor/monaditto/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bardoor%2Fmonaditto/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278547821,"owners_count":26004775,"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","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"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":["elixir","functional-programming","monad"],"created_at":"2025-10-06T02:11:58.652Z","updated_at":"2025-10-06T02:12:13.712Z","avatar_url":"https://github.com/bardoor.png","language":"Elixir","readme":"# Monaditto\n\n[![Elixir CI](https://github.com/bardoor/monaditto/actions/workflows/elixir.yml/badge.svg)](https://github.com/bardoor/monaditto/actions/workflows/elixir.yml)\n[![Hex.pm Version](https://img.shields.io/hexpm/v/monaditto.svg)](https://hex.pm/packages/monaditto)\n[![Hex.pm Downloads](https://img.shields.io/hexpm/dt/monaditto.svg)](https://hex.pm/packages/monaditto)\n[![Documentation](https://img.shields.io/badge/docs-hexdocs-blue.svg)](https://hexdocs.pm/monaditto)\n\n\u003e *\"Behold, traveler, and let thine eyes witness monads for Elixir, lest they transform thee into a basement-dwelling dev and hikki of code\"*\n\nA pragmatic monad library for Elixir that works with your existing `{:ok, value} | {:error, reason}` code. No fancy wrapper types, no category theory PhD required, just good old Elixir tuples doing monad things.\n\n## Why though?\n\nYou're already using monads every day in Elixir:\n\n```elixir\njose = %{first_name: \"Jose\", last_name: \"Valim\"}\n{:ok, \"Jose\"} = Map.fetch(jose, :first_name)    # Maybe monad says hello\n:error = Map.fetch(jose, :age)                  # Maybe monad says goodbye\n```\n\nBut then you end up with code like this:\n\n```elixir\ncase fetch_user(id) do\n  {:ok, user} -\u003e\n    case get_email(user) do\n      {:ok, email} -\u003e\n        case send_notification(email) do\n          {:ok, result} -\u003e {:ok, result}\n          {:error, reason} -\u003e {:error, reason}\n        end\n      {:error, reason} -\u003e {:error, reason}\n    end\n  {:error, reason} -\u003e {:error, reason}\nend\n```\n\nOf course, you can make some improvements:\n```elixir\nwith {:ok, user} \u003c- fetch_user(id),\n     {:ok, email} \u003c- get_email(user) do\n  send_notification(email)\nend\n```\n\nBut with `Monaditto` you can rock it even better!\n\n## The Better Way™\n\n```elixir\nuser_id\n|\u003e fetch_user()                    # {:ok, %User{}} | {:error, :not_found}\n|\u003e Monad.map(\u0026get_email/1)         # {:ok, \"user@example.com\"} | {:error, :not_found}\n|\u003e Monad.map(\u0026send_notification/1) # {:ok, :sent} | {:error, :not_found}\n```\n\nClean, readable, and your error handling is automagically short-circuited. Like `with` statements, but with more style points.\n\n## Installation\n\nAdd `monaditto` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:monaditto, \"~\u003e 0.4.0\"}\n  ]\nend\n```\n\n## Quick Start\n\n```elixir\n# Basic mapping\n{:ok, \"hello\"}\n|\u003e Monad.map(\u0026String.upcase/1)\n|\u003e Monad.map(\u0026String.reverse/1)\n# =\u003e {:ok, \"OLLEH\"}\n\n# Error short-circuiting\n{:error, :oops}\n|\u003e Monad.map(\u0026String.upcase/1)  # Nope, not happening\n|\u003e Monad.map(\u0026String.reverse/1) # Still nope\n# =\u003e {:error, :oops}\n\n# Safe operations\nMonad.safe(fn -\u003e 1 / 0 end)\n# =\u003e {:error, %ArithmeticError{...}}\n\n# Processing lists\n[{:ok, 1}, {:ok, 2}, {:ok, 3}]\n|\u003e Monad.traverse(\u0026({:ok, \u00261 * 2}))\n# =\u003e {:ok, [2, 4, 6]}\n```\n\n## Available Functions\n\n- `map/2` - Transform success values\n- `map_error/2` - Transform error values\n- `flat_map/2` - Chain operations that return results\n- `bimap/3` - Transform both success and error cases\n- `peek/2` - Side effects without changing the value\n- `traverse/2` - Map and sequence combined\n- `sequence/2` - Unwrap lists of results\n- `safe/2` - Wrap dangerous operations\n- `unwrap/2` \u0026 `unwrap!/1` - Extract values (carefully)\n- `any_error?/1` \u0026 `all_ok?/1` - Validation helpers\n\n## Philosophy\n\nThis library embraces Elixir's \"let it crash\" mentality while giving you tools to handle errors gracefully when you need to. We're not trying to turn Elixir into Haskell (though Haskell is lovely). We're just making your existing error-handling patterns more composable and less nested.\n\nNo magic, no surprises, just functions that do what they say on the tin.\n\n## Documentation\n\nFull documentation is available at [HexDocs](https://hexdocs.pm/monaditto) (when we publish it).\n\n## Contributing\n\nFound a bug? Have an idea? PRs welcome! Just remember: keep it simple, keep it pragmatic, keep it Elixir-y.\n\n## License\n\nMIT License. Because sharing is caring, and lawyers are expensive.\n\n---\n\n*Made with ❤️ and a healthy dose of functional programming enthusiasm*\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbardoor%2Fmonaditto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbardoor%2Fmonaditto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbardoor%2Fmonaditto/lists"}