# darkcore
**darkcore** is a lightweight functional programming toolkit for Python.
It brings **Functor / Applicative / Monad** abstractions, classic monads like **Maybe, Either/Result, Reader, Writer, State**,
and an expressive **operator DSL** (`|`, `>>`, `@`) that makes Python feel almost like Haskell.
---
## ✨ Features
- Functor / Applicative / Monad base abstractions
- Core monads implemented:
- `Maybe` — handle missing values
- `Either` / `Result` — safe error handling
- `Reader` — dependency injection / environment
- `Writer` — accumulate logs
- `State` — stateful computations
- Monad transformer: `MaybeT`
- Operator overloads for concise DSL-style code:
- `|` → `fmap` (map)
- `>>` → `bind` (flatMap)
- `@` → `ap` (applicative apply)
- High test coverage, Monad law tests included
---
## 🚀 Installation
```bash
pip install darkcore
```
(or use Poetry)
---
## 🧪 Quick Examples
### Maybe
```python
from darkcore.maybe import Maybe
m = Maybe(3) | (lambda x: x+1) >> (lambda y: Maybe(y*2))
print(m) # Just(8)
n = Maybe(None) | (lambda x: x+1)
print(n) # Nothing
```
---
### Result
```python
from darkcore.result import Ok, Err
def parse_int(s: str):
try:
return Ok(int(s))
except ValueError:
return Err(f"invalid int: {s}")
res = parse_int("42") >> (lambda x: Ok(x * 2))
print(res) # Ok(84)
res2 = parse_int("foo") >> (lambda x: Ok(x * 2))
print(res2) # Err("invalid int: foo")
```
---
### Reader
```python
from darkcore.reader import Reader
get_user = Reader(lambda env: env["user"])
greet = get_user | (lambda u: f"Hello {u}")
print(greet.run({"user": "Alice"})) # "Hello Alice"
```
---
### Writer
```python
from darkcore.writer import Writer
w = Writer.pure(3).tell("start") >> (lambda x: Writer(x+1, ["inc"]))
print(w) # Writer(4, log=['start', 'inc'])
```
---
### State
```python
from darkcore.state import State
inc = State(lambda s: (s, s+1))
prog = inc >> (lambda x: State(lambda s: (x+s, s)))
print(prog.run(1)) # (3, 2)
```
---
## 📖 Integration Example
```python
from darkcore.reader import Reader
from darkcore.writer import Writer
from darkcore.state import State
from darkcore.result import Ok, Err
# Reader: get user from environment
get_user = Reader(lambda env: env.get("user"))
# Result: validate existence
to_result = lambda user: Err("no user") if user is None else Ok(user)
# Writer: log user
log_user = lambda user: Writer(user, [f"got user={user}"])
# State: update counter
update_state = lambda user: State(lambda s: (f"{user}@{s}", s+1))
env = {"user": "alice"}
user = get_user.run(env)
res = to_result(user) >> (lambda u: Ok(log_user(u)))
writer = res.value
print(writer.log) # ['got user=alice']
out, s2 = update_state(writer.value).run(42)
print(out, s2) # alice@42 43
```
---
## Why?
- **Safer business code**
- Avoid nested `try/except` and `if None` checks
- Express computations declaratively with monads
- **Educational value**
- Learn Haskell/FP concepts hands-on in Python
- **Expressive DSL**
- `|`, `>>`, `@` make pipelines concise and clear
---
## Development
```bash
git clone https://github.com/YOURNAME/darkcore
cd darkcore
poetry install
poetry run pytest -v --cov=darkcore
```
---
## License
MIT
Raw data
{
"_id": null,
"home_page": "https://github.com/yourname/darkcore",
"name": "darkcore",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.12",
"maintainer_email": null,
"keywords": "monad, functional, dsl, business logic",
"author": "minamorl",
"author_email": "minamorl@users.noreply.github.com",
"download_url": "https://files.pythonhosted.org/packages/55/72/fd5b8ed72cc0231894d19423c812faf9c1a0097188aa6d5cfacf7c08499e/darkcore-0.1.1.tar.gz",
"platform": null,
"description": "# darkcore\n\n**darkcore** is a lightweight functional programming toolkit for Python. \nIt brings **Functor / Applicative / Monad** abstractions, classic monads like **Maybe, Either/Result, Reader, Writer, State**, \nand an expressive **operator DSL** (`|`, `>>`, `@`) that makes Python feel almost like Haskell.\n\n---\n\n## \u2728 Features\n\n- Functor / Applicative / Monad base abstractions\n- Core monads implemented:\n - `Maybe` \u2014 handle missing values\n - `Either` / `Result` \u2014 safe error handling\n - `Reader` \u2014 dependency injection / environment\n - `Writer` \u2014 accumulate logs\n - `State` \u2014 stateful computations\n- Monad transformer: `MaybeT`\n- Operator overloads for concise DSL-style code:\n - `|` \u2192 `fmap` (map)\n - `>>` \u2192 `bind` (flatMap)\n - `@` \u2192 `ap` (applicative apply)\n- High test coverage, Monad law tests included\n\n---\n\n## \ud83d\ude80 Installation\n\n```bash\npip install darkcore\n```\n\n(or use Poetry)\n\n---\n\n## \ud83e\uddea Quick Examples\n\n### Maybe\n\n```python\nfrom darkcore.maybe import Maybe\n\nm = Maybe(3) | (lambda x: x+1) >> (lambda y: Maybe(y*2))\nprint(m) # Just(8)\n\nn = Maybe(None) | (lambda x: x+1)\nprint(n) # Nothing\n```\n\n---\n\n### Result\n\n```python\nfrom darkcore.result import Ok, Err\n\ndef parse_int(s: str):\n try:\n return Ok(int(s))\n except ValueError:\n return Err(f\"invalid int: {s}\")\n\nres = parse_int(\"42\") >> (lambda x: Ok(x * 2))\nprint(res) # Ok(84)\n\nres2 = parse_int(\"foo\") >> (lambda x: Ok(x * 2))\nprint(res2) # Err(\"invalid int: foo\")\n```\n\n---\n\n### Reader\n\n```python\nfrom darkcore.reader import Reader\n\nget_user = Reader(lambda env: env[\"user\"])\ngreet = get_user | (lambda u: f\"Hello {u}\")\n\nprint(greet.run({\"user\": \"Alice\"})) # \"Hello Alice\"\n```\n\n---\n\n### Writer\n\n```python\nfrom darkcore.writer import Writer\n\nw = Writer.pure(3).tell(\"start\") >> (lambda x: Writer(x+1, [\"inc\"]))\nprint(w) # Writer(4, log=['start', 'inc'])\n```\n\n---\n\n### State\n\n```python\nfrom darkcore.state import State\n\ninc = State(lambda s: (s, s+1))\nprog = inc >> (lambda x: State(lambda s: (x+s, s)))\n\nprint(prog.run(1)) # (3, 2)\n```\n\n---\n\n## \ud83d\udcd6 Integration Example\n\n```python\nfrom darkcore.reader import Reader\nfrom darkcore.writer import Writer\nfrom darkcore.state import State\nfrom darkcore.result import Ok, Err\n\n# Reader: get user from environment\nget_user = Reader(lambda env: env.get(\"user\"))\n\n# Result: validate existence\nto_result = lambda user: Err(\"no user\") if user is None else Ok(user)\n\n# Writer: log user\nlog_user = lambda user: Writer(user, [f\"got user={user}\"])\n\n# State: update counter\nupdate_state = lambda user: State(lambda s: (f\"{user}@{s}\", s+1))\n\nenv = {\"user\": \"alice\"}\n\nuser = get_user.run(env)\nres = to_result(user) >> (lambda u: Ok(log_user(u)))\nwriter = res.value\nprint(writer.log) # ['got user=alice']\n\nout, s2 = update_state(writer.value).run(42)\nprint(out, s2) # alice@42 43\n```\n\n---\n\n## Why?\n\n- **Safer business code** \n - Avoid nested `try/except` and `if None` checks \n - Express computations declaratively with monads \n- **Educational value** \n - Learn Haskell/FP concepts hands-on in Python \n- **Expressive DSL** \n - `|`, `>>`, `@` make pipelines concise and clear \n\n---\n\n## Development\n\n```bash\ngit clone https://github.com/YOURNAME/darkcore\ncd darkcore\npoetry install\npoetry run pytest -v --cov=darkcore\n```\n\n---\n\n## License\n\nMIT\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Practical functional programming primitives for Python: Monads, Transformers, and DSL operators for safe business logic",
"version": "0.1.1",
"project_urls": {
"Homepage": "https://github.com/yourname/darkcore",
"Repository": "https://github.com/yourname/darkcore"
},
"split_keywords": [
"monad",
" functional",
" dsl",
" business logic"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "86749fddf9b25d152591c8ff9a1ee19629ebc37ab864042ee4a175eca625fd20",
"md5": "ec37560d5a6ecb35805b1d0af4c9b166",
"sha256": "11a7f0ffb89b331a95d40ef300aae50d45252ea3137b188652a853ec8323886f"
},
"downloads": -1,
"filename": "darkcore-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ec37560d5a6ecb35805b1d0af4c9b166",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.12",
"size": 10782,
"upload_time": "2025-08-16T19:01:33",
"upload_time_iso_8601": "2025-08-16T19:01:33.542951Z",
"url": "https://files.pythonhosted.org/packages/86/74/9fddf9b25d152591c8ff9a1ee19629ebc37ab864042ee4a175eca625fd20/darkcore-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5572fd5b8ed72cc0231894d19423c812faf9c1a0097188aa6d5cfacf7c08499e",
"md5": "bc71ae25d374410ef21db8f5de5021a4",
"sha256": "d16e87dabc05996ce65a1607251c4c1cdea02309b06b623ca3b36cc8113bbf76"
},
"downloads": -1,
"filename": "darkcore-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "bc71ae25d374410ef21db8f5de5021a4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.12",
"size": 8032,
"upload_time": "2025-08-16T19:01:34",
"upload_time_iso_8601": "2025-08-16T19:01:34.745485Z",
"url": "https://files.pythonhosted.org/packages/55/72/fd5b8ed72cc0231894d19423c812faf9c1a0097188aa6d5cfacf7c08499e/darkcore-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-16 19:01:34",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "yourname",
"github_project": "darkcore",
"github_not_found": true,
"lcname": "darkcore"
}