Source code for monawhat.base

"""Module implementing a base monad class that all other monads can extend."""

from typing import TypeVar, Generic, Any
from collections.abc import Callable

from monawhat.identity import Identity

M = TypeVar("M", bound="BaseMonad[Any]")  # Monad type (for return type of bind/map)
A = TypeVar("A")  # Input type
B = TypeVar("B")  # Output type


[docs] class BaseMonad(Generic[A]): """Base class for all monads. This class provides common functionality for monads and serves as a foundation for implementing specific monads. It uses the Identity monad internally for pure values. Subclasses must implement _bind_implementation and _map_implementation. """
[docs] def map(self, f: Callable[[A], B]) -> "BaseMonad[B]": """Apply a function to the value(s) inside the monad. Args: f: The function to apply to the value(s). Returns: A new monad with the transformed value(s). """ return self._map_implementation(f)
[docs] def bind(self, f: Callable[[A], Any]) -> Any: """Chain this monad with a function that returns another monad. Args: f: A function that takes the value(s) of this monad and returns a new monad. Returns: The new monad returned by the function. """ return self._bind_implementation(f)
def _map_implementation(self, f: Callable[[A], B]) -> "BaseMonad[B]": """Implementation of the map operation for this specific monad. Subclasses must override this method to provide monad-specific behavior. Args: f: The function to apply to the value(s). Returns: A new monad with the transformed value(s). """ raise NotImplementedError("Subclasses must implement this") def _bind_implementation(self, f: Callable[[A], Any]) -> Any: """Implementation of the bind operation for this specific monad. Subclasses must override this method to provide monad-specific behavior. Args: f: A function that takes the value(s) of this monad and returns a new monad. Returns: The new monad returned by the function. """ raise NotImplementedError("Subclasses must implement this")
[docs] @classmethod def pure(cls, value: A, *args: Any, **kwargs: Any) -> "BaseMonad[A]": """Create a monad containing a pure value. This uses the Identity monad internally to represent pure values. Subclasses should override this to provide monad-specific implementation. Args: value: The value to wrap in the monad. *args: Additional positional arguments for specific monad implementations. **kwargs: Additional keyword arguments for specific monad implementations. Returns: A monad containing the value. """ return cls._pure_implementation(Identity(value).get(), *args, **kwargs)
@classmethod def _pure_implementation(cls, value: A, *args: Any, **kwargs: Any) -> "BaseMonad[A]": """Implementation of the pure operation for this specific monad. Subclasses must override this method to provide monad-specific behavior. Args: value: The value to wrap in the monad. *args: Additional positional arguments for specific monad implementations. **kwargs: Additional keyword arguments for specific monad implementations. Returns: A monad containing the value. """ raise NotImplementedError("Subclasses must implement this")