Python Functional programming library: Functools
Let’s explore how to use the functools module in Python to create a simple monadic behavior. While Python doesn’t enforce monads as strictly as Haskell, we can still demonstrate some functional concepts.
- Caching with
@cache(formerly@lru_cache):
- The
@cachedecorator allows you to create a lightweight function cache. It memoizes results, speeding up calculations. - Here’s an example using the Fibonacci series:
from functools import cache @cache def fibonacci(n: int) -> int: if n <= 1: return n return fibonacci(n - 1) + fibonacci(n - 2) print(fibonacci(10)) # Cached result: 55 print(fibonacci(5)) # Cached result: 5 - The
@cachedecorator ensures that previously computed results are reused, avoiding redundant calculations⁴.
- Maybe-Like Behavior:
- While not a strict monad, we can create a simple “Maybe-like” behavior using a custom class:
class Maybe: def __init__(self, value): self.value = value def map(self, func): if self.value is not None: return Maybe(func(self.value)) else: return Maybe(None) def add_one(x): return x + 1def double(x): return x * 2maybe_result = Maybe(3).map(add_one).map(double) print(maybe_result.value) # Result: 8maybe_none = Maybe(None).map(add_one).map(double) print(maybe_none.value) # Result: None- In this example, the
Maybeclass wraps a value and applies functions only if the value is notNone³.
Remember that Python’s approach to monads is more flexible and pragmatic, but Haskell remains the gold standard for enforcing functional purity and type safety. 🌟🐍🔗
Source: Conversation with Copilot, 6/6/2024
(1) 6 Cool Things You Can Do With The Functools Module. https://pybit.es/articles/6-cool-things-you-can-do-with-the-functools-module/.
(2) ArjanCodes | Python Functors and Monads: A Practical Guide. https://www.arjancodes.com/blog/python-functors-and-monads/.
(3) functools — Higher-order functions and operations on … – Python. https://docs.python.org/3/library/functools.html.
(4) A short, hands-on introduction to Functors and Monads using Python. https://medium.com/@oikonomod/a-short-hands-on-introduction-to-functors-and-monads-using-python-6544b5739f3d.
(5) Functools module in Python – GeeksforGeeks. https://www.geeksforgeeks.org/functools-module-in-python/.
Comonad Use
Certainly! Let’s incorporate a simple example of a comonad in Haskell. While the Maybe monad is more commonly discussed, we can create a comonad-like behavior using the Store Comonad.
- Store Comonad:
- The Store comonad represents a value with an associated context (or “store”). It allows us to extract information from the context.
- We’ll create a basic Store comonad that holds a value and its index in a list.
- Example:
import Control.Comonad -- Define a Store comonad data Store s a = Store [a] s instance Functor (Store s) where fmap f (Store xs s) = Store (fmap f xs) s instance Comonad (Store s) where extract (Store xs s) = xs !! s duplicate (Store xs s) = Store (Store <$> tails xs <*> pure s) s -- Example usage main :: IO () main = do let myList = [10, 20, 30, 40, 50] store = Store myList 2 -- Value 30, index 2 putStrLn $ "Extracted value: " ++ show (extract store) putStrLn $ "Context (duplicated): " ++ show (duplicate store)
- In this example:
- We define a
Storedata type that holds a list of values and an index. - The
Functorinstance applies a function to each value in the list. - The
Comonadinstance providesextract(to get the current value) andduplicate(to create a new Store with all possible contexts). - We create a Store with the value 30 (index 2) and demonstrate extraction and duplication.
- We define a
Remember that comonads are less commonly used than monads, but they provide a dual perspective on context and computation. 🌟🐦🔗 Let me know if you’d like further details or additional examples! 😊
Certainly! Let’s incorporate a simple example of a comonad in Haskell. While the Maybe monad is more commonly discussed, we can create a comonad-like behavior using the Store Comonad.
- Store Comonad:
- The Store comonad represents a value with an associated context (or “store”). It allows us to extract information from the context.
- We’ll create a basic Store comonad that holds a value and its index in a list.
- Example:
import Control.Comonad -- Define a Store comonad data Store s a = Store [a] s instance Functor (Store s) where fmap f (Store xs s) = Store (fmap f xs) s instance Comonad (Store s) where extract (Store xs s) = xs !! s duplicate (Store xs s) = Store (Store <$> tails xs <*> pure s) s -- Example usage main :: IO () main = do let myList = [10, 20, 30, 40, 50] store = Store myList 2 -- Value 30, index 2 putStrLn $ "Extracted value: " ++ show (extract store) putStrLn $ "Context (duplicated): " ++ show (duplicate store)
- In this example:
- We define a
Storedata type that holds a list of values and an index. - The
Functorinstance applies a function to each value in the list. - The
Comonadinstance providesextract(to get the current value) andduplicate(to create a new Store with all possible contexts). - We create a Store with the value 30 (index 2) and demonstrate extraction and duplication.
- We define a
Remember that comonads are less commonly used than monads, but they provide a dual perspective on context and computation. 🌟🐦🔗 Let me know if you’d like further details or additional examples! 😊


