A comprehensive monad library for mq - bringing functional programming patterns to Markdown processing.
Note
This is a hobby project exploring functional programming concepts within the mq.
monad.mq provides a collection of monadic abstractions inspired by Clojure's algo.monads library, implemented for the mq language. It enables elegant composition of computations while working with Markdown and structured data.
- Multiple Monad Implementations
- Identity Monad - Basic monadic structure
- Maybe Monad - Null-safe computations
- List Monad - Non-deterministic computations
- State Monad - Stateful computations
- Writer Monad - Computations with logging
- Reader Monad - Environment-based computations
- Either Monad - Error handling with Left/Right values
- Unified Do Notation -
domonadsyntax for cleaner monadic composition - Helper Functions - Rich set of utilities including
m_sequence,m_map,m_comp,m_filter, etc. - MonadPlus Support - Zero and plus operations for applicable monads
include "monad"
def safe_divide(a, b):
if (b == 0):
None
else:
a / b
end
domonad(
maybe_m(),
[
bind("x", safe_divide(10, 2)),
bind("y", safe_divide(20, 4))
],
fn(vars): maybe_return(vars["x"] + vars["y"]);
)
# Result: 10
include "monad"
pythagorean_triples(15)
# Result: [[3,4,5], [6,8,10], [5,12,13], [9,12,15]]
include "monad"
def parse_int(str):
let num = to_number(str)
| if (is_none(num)):
either_left("Invalid number: " + str)
else:
either_right(num)
end
domonad(
either_m(),
[
bind("a", parse_int("42")),
bind("b", parse_int("10"))
],
fn(vars): either_return(vars["a"] + vars["b"]);
)
# Result: {"type": "right", "value": 52}
| Monad | Purpose | Key Functions |
|---|---|---|
| Identity | Basic composition | identity_return, identity_bind |
| Maybe | Null safety | maybe_return, maybe_bind, maybe_zero |
| List | Non-determinism | list_return, list_bind, list_zero |
| State | Stateful computation | state_get, state_put, state_modify, run_state |
| Writer | Logging | writer_return, writer_tell |
| Reader | Environment access | reader_return, ask, asks, local, run_reader |
| Either | Error handling | either_left, either_right, is_left, is_right |
m_sequence(monad_def, ms)- Convert list of monadic values to monadic listm_map(monad_def, list, f)- Map monadic function over listm_comp(monad_def, f, g)- Compose monadic functionsm_lift(monad_def, f)- Lift regular function into monadm_filter(monad_def, list, pred)- Filter with monadic predicatem_when(monad_def, condition, action)- Conditional executionm_unless(monad_def, condition, action)- Negated conditional execution
The library includes comprehensive examples demonstrating:
- Safe division with Maybe monad
- Non-deterministic pairs with List monad
- Counter with State monad
- Logging with Writer monad
- Error handling with Either monad
- Sequencing operations
- Function composition
- Pythagorean triples generation
- Configuration management with Reader monad
See the source code for complete example implementations.
# Use the library in your mq scripts
mq 'include "monad" | example_maybe()' file.md
# Run with specific monad operations
mq 'include "monad" | pythagorean_triples(20)' file.md- mq - Command-line tool for processing Markdown
This project is licensed under the MIT License.
- mq - The mq language and CLI tool
- Clojure algo.monads - Inspiration for this library