Monad
In functional programming, monads are a way to structure computations as a sequence of steps, where each step not onlyi produces a value but also some extra information about the computation, such as a potential failure, non-determinism, or side effect.
We will see who to implement monad with python only for help python developer too understand.
Properties

- Wrapper Type
- wrap function
- alows entry to monad exosystem alsoknow as return, pure, unit
- alows entry to monad exosystem alsoknow as return, pure, unit
- Run function
Examples
Monad Maybe
So, We will start with monad monad Maybe for the first example.
why is the utility of Maybe ?
Is great way to generalize exception of None value (we don't like None..).
with Monad Maybe we can chain multip operation with no need to check the result of the value None. We need to check only on end
def add_one(x: int) -> int:
return x + 1
def double(x: int) -> int:
return x * 2
result = Maybe(3).bind(add_one).bind(double)
print(result) # Just 8
result = Maybe(None).bind(add_one).bind(double)
print(result) # Nothing
result = Maybe(None).bind(add_one).bind(double).orElse(10)
print(result) # Just 10
result = Maybe(None) | Maybe(1)
print(result) # Just 1The naif implementation of the monad Maybe can be:
class Maybe:
def __init__(self, value):
self._value = value
def bind(self, func):
if self._value is None:
return Maybe(None)
else:
return Maybe(func(self._value))
def orElse(self, default):
if self._value is None:
return Maybe(default)
else:
return self
def unwrap(self):
return self._value
def __or__(self, other):
return Maybe(self._value or other._value)
def __str__(self):
if self._value is None:
return 'Nothing'
else:
return 'Just {}'.format(self._value)
def __repr__(self):
return str(self)
def __eq__(self, other):
if isinstance(other, Maybe):
return self._value == other._value
else:
return False
def __ne__(self, other):
return not (self == other)
def __bool__(self):
return self._value is not None
Monad IO
- Encapsulates IO operations
- Chains operations without executing them immediately
- Runs them later in a controlled manner
We mask a error and the implementation of io function to only focus on the what we whant do.
for this example we well print the and of log with filtering level.
if __name__ == "__main__":
filename = "example.log"
io_action = (
read_file(filename)
.bind(lambda content: tail(content, 10))
.bind(lambda content: filter_level(content, "ERROR"))
.bind(print_lines)
)
# ---
io_action.run()
The implementation of the monad is very simple
from typing import Callable, Any
class IOMonad:
def __init__(self, action: Callable[[], Any]):
self.action = action # A function that returns a value
def bind(self, func: Callable[[Any], "IOMonad"]) -> "IOMonad":
return IOMonad(action=lambda: func(self.run()).run())
def run(self) -> Any:
return self.action()
def read_file(filename: str) -> IOMonad:
return IOMonad(lambda: open(filename).read().splitlines())
def tail(lines: list, count: int = 10) -> IOMonad:
return IOMonad(lambda: lines[-count:])
def filter_level(lines: list, level: str) -> IOMonad:
return IOMonad(lambda: [line for line in lines if level in line])
def print_lines(lines: list) -> IOMonad:
return IOMonad(lambda: print("\n".join(lines) if lines else "No WARNING messages found."))
conclusion
Monads are a design patternthat allows a user to chain operations while the monad manages secret behind the scenes.

thanks for reading, go further

Very good resource to learn hackell and functional programing https://exercism.org/tracks/haskell/exercises

