{"id":16715442,"url":"https://github.com/dbrattli/oslash","last_synced_at":"2025-11-17T02:03:26.299Z","repository":{"id":28333238,"uuid":"31846390","full_name":"dbrattli/OSlash","owner":"dbrattli","description":"Functors, Applicatives, And Monads in Python","archived":false,"fork":false,"pushed_at":"2024-04-20T21:48:01.000Z","size":227,"stargazers_count":736,"open_issues_count":13,"forks_count":51,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-09-28T23:16:05.173Z","etag":null,"topics":["functors","monad-tutorial","monads","oslash","python"],"latest_commit_sha":null,"homepage":"","language":"Python","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/dbrattli.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2015-03-08T10:46:11.000Z","updated_at":"2025-09-20T05:56:31.000Z","dependencies_parsed_at":"2024-01-18T14:39:52.923Z","dependency_job_id":"a78e078c-ebe5-4014-8792-cf78e3899728","html_url":"https://github.com/dbrattli/OSlash","commit_stats":{"total_commits":190,"total_committers":8,"mean_commits":23.75,"dds":0.04210526315789476,"last_synced_commit":"c271c7633daf9d72393b419cfc9229e427e6a42a"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/dbrattli/OSlash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbrattli%2FOSlash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbrattli%2FOSlash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbrattli%2FOSlash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbrattli%2FOSlash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dbrattli","download_url":"https://codeload.github.com/dbrattli/OSlash/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbrattli%2FOSlash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000741,"owners_count":26082932,"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-09T02:00:07.460Z","response_time":59,"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":["functors","monad-tutorial","monads","oslash","python"],"created_at":"2024-10-12T21:09:25.182Z","updated_at":"2025-11-17T02:03:26.282Z","avatar_url":"https://github.com/dbrattli.png","language":"Python","readme":"# Functors, Applicatives, And Monads in Python\n\n[![CI](https://github.com/dbrattli/OSlash/workflows/CI/badge.svg)](https://github.com/dbrattli/OSlash/actions)\n[![PyPI](https://img.shields.io/pypi/v/oslash.svg)](https://pypi.org/project/oslash/)\n[![Python Version](https://img.shields.io/pypi/pyversions/oslash.svg)](https://pypi.org/project/oslash/)\n[![License](https://img.shields.io/github/license/dbrattli/OSlash.svg)](https://github.com/dbrattli/OSlash/blob/master/LICENSE)\n\nOSlash (Ø) is a library for learning and understanding functional programming in Python 3.12+. It re-implements\nconcepts from [Learn You a Haskell for Great Good!](http://learnyouahaskell.com/) using Python with modern type annotations. OSlash unifies\nfunctional and object-oriented paradigms by grouping related functions within classes. Objects are never used\nfor storing values or mutable data; data exists only within function closures.\n\n## ✨ What's New in 1.0\n\n**OSlash 1.0 is a complete modernization** for Python 3.12+:\n\n- **Modern Type System**: Fully type-checked with Pyright in strict mode\n- **PEP 695 Syntax**: Clean type parameters (`class Maybe[T]:` instead of `Generic[T]`)\n- **Modern Tooling**: Built with uv, formatted with ruff, validated with pre-commit hooks\n- **Production Status**: Stable release ready for educational use\n\n**Type Safety**: OSlash is fully type-checked with Pyright in strict mode, providing excellent IDE support and catching errors at development time. It leverages Python 3.12's PEP 695 type parameter syntax for clean, ergonomic generic types.\n\nOSlash is intended to be a tutorial. For practical functional programming in Python in production environments you\nshould consider using [Expression](https://github.com/dbrattli/Expression) instead.\n\n## Install\n\n```bash\n# Using pip\npip install oslash\n\n# Or using uv (recommended)\nuv add oslash\n```\n\nThe project currently contains implementations for:\n\n## Abstract Base Classes\n\n- **[Functor](https://github.com/dbrattli/OSlash/wiki/Functors,-Applicatives,-And-Monads-In-Pictures#functors)**, for stuff that can be mapped\n- **[Applicative](https://github.com/dbrattli/OSlash/wiki/Functors,-Applicatives,-And-Monads-In-Pictures#applicatives)**, for callable stuff\n- **Monoid**, for associative stuff\n- **[Monad](https://github.com/dbrattli/OSlash/wiki/Functors,-Applicatives,-And-Monads-In-Pictures#monads)**, for monadic stuff\n\n## And Some Monads\n\n- **Identity**, boxed stuff in its simplest form\n- **[Maybe (Just | Nothing)](https://github.com/dbrattli/oslash/wiki/Functors,-Applicatives,-And-Monads-In-Pictures)**, for optional stuff\n- **Either (Right | Left)**, for possible failures\n- **List**, purely functional list of stuff\n- **[IO Action](https://github.com/dbrattli/OSlash/wiki/Functors,-Applicatives,-And-Monads-In-Pictures#io-monad)**, for impure stuff\n- **[Writer](https://github.com/dbrattli/OSlash/wiki/Three-Useful-Monads#the-writer-monad)**, for logging stuff\n- **[Reader](https://github.com/dbrattli/OSlash/wiki/Three-Useful-Monads#the-reader-monad)**, for callable stuff\n- **State**, for stateful computations of stuff\n- **Cont**, for continuation of stuff\n\n## Monadic functions\n\n- **\u003e\u003e**, for sequencing monadic actions\n- **lift**, for mapping a function over monadic values\n- **join**, for removing one level of monadic structure\n- **compose**, for composing monadic functions\n\n## Utility functions\n\n- **compose**, for composing 0 to n functions\n\n## But why?\n\nYes, I know there are other projects out there like [PyMonad](https://bitbucket.org/jason_delaat/pymonad/),\n[fn.py](https://github.com/kachayev/fn.py). I'm simply doing this in order to better understand the\n[book](http://learnyouahaskell.com/). It's so much easier to learn when you implement things yourself. The code may be\nsimilar to PyMonad in structure, but is quite different in implementation.\n\nWhy is the project called OSlash? OSlash is the Norwegian character called [Oslash](http://en.wikipedia.org/wiki/Ø).\nInitially I wanted to create a project that used Ø and ø (unicode) for the project name and modules. It didn't work out\nwell, so I renamed it to OSlash.\n\n## Examples\n\nHaskell:\n\n```haskell\n\u003e fmap (+3) (Just 2)\nJust 5\n\n\u003e (+3) \u003c$\u003e (Just 2)\nJust 5\n```\n\nPython:\n\n```python\n\u003e\u003e\u003e Just(2).map(lambda x: x+3)\nJust 5\n\n\u003e\u003e\u003e (lambda x: x+3) % Just(2)\nJust 5\n\n```\n\nIO Actions:\n\n```python\nfrom oslash import put_line, get_line\n\nmain = put_line(\"What is your name?\") | (lambda _:\n    get_line() | (lambda name:\n    put_line(\"What is your age?\") | (lambda _:\n    get_line() | (lambda age:\n    put_line(\"Hello \" + name + \"!\") | (lambda _:\n    put_line(\"You are \" + age + \" years old\"))))))\n\nif __name__ == \"__main__\":\n    main()\n```\n\n## Tutorials\n\n- [Functors, Applicatives, And Monads In Pictures](https://github.com/dbrattli/oslash/wiki/Functors,-Applicatives,-And-Monads-In-Pictures) in Python.\n- [Three Useful Monads](https://github.com/dbrattli/OSlash/wiki/Three-Useful-Monads) _(in progress)_\n- [Using Either monad in Python](https://medium.com/@rnesytov/using-either-monad-in-python-b6eac698dff5)\n","funding_links":[],"categories":["Awesome Functional Python"],"sub_categories":["Libraries"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbrattli%2Foslash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdbrattli%2Foslash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbrattli%2Foslash/lists"}