aboutsummaryrefslogtreecommitdiff
path: root/python/src/types/monad.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/src/types/monad.py')
-rw-r--r--python/src/types/monad.py80
1 files changed, 0 insertions, 80 deletions
diff --git a/python/src/types/monad.py b/python/src/types/monad.py
deleted file mode 100644
index f09ff33..0000000
--- a/python/src/types/monad.py
+++ /dev/null
@@ -1,80 +0,0 @@
-from functools import wraps
-from typing import Callable
-
-from .selection import Selection
-from .state import EditorState, Result, StateChange
-
-
-class StateMonad:
- def __init__(self, run_fn: Callable[[EditorState], Result]):
- self._run_fn = run_fn
-
- def run(self, state: EditorState) -> Result:
- return self._run_fn(state)
-
- def commit(self, state: EditorState) -> tuple[Selection, EditorState]:
- sel, changes = self.run(state)
- state.commit_changes(changes)
- return (sel, state)
-
- def bind(self, f: Callable[[Selection], "StateMonad"]) -> "StateMonad":
- def run_bound(state: EditorState) -> Result:
- sel1, changes1 = self.run(state)
- expr2 = f(sel1)
- sel2, changes2 = expr2.run(state)
- return (sel2, changes1 + changes2)
-
- return StateMonad(run_bound)
-
- @staticmethod
- def pure(selection: Selection) -> "StateMonad":
- def run_pure(_: EditorState) -> Result:
- return (selection, [])
-
- return StateMonad(run_pure)
-
- def modify(change: StateChange, selection: Selection) -> "StateMonad":
- def run_modify(_: EditorState) -> Result:
- return (selection, [change])
-
- return StateMonad(run_modify)
-
-
-def monadic(
- func: Callable[[Selection, EditorState], Result],
-) -> Callable[[Selection | StateMonad], StateMonad]:
- def make_monad(sel: Selection) -> StateMonad:
- def run_fn(state: EditorState) -> Result:
- return func(sel, state)
-
- return StateMonad(run_fn)
-
- @wraps(func)
- def wrapper(arg: Selection | StateMonad) -> StateMonad:
- if isinstance(arg, StateMonad):
- return arg.bind(make_monad)
- else:
- return make_monad(arg)
-
- return wrapper
-
-
-def group(*exprs: StateMonad) -> StateMonad:
- def run_grouped(state: EditorState) -> Result:
- all_selections = []
- all_changes = []
-
- for expr in exprs:
- sel, changes = expr.run(state)
- all_selections.append(sel)
- all_changes.extend(changes)
-
- # TODO: Check for any overlapping changes
- # TODO: Merge selections into union
-
- return (
- all_selections[0] if all_selections else state.current_selection,
- all_changes,
- )
-
- return StateMonad(run_grouped)