### Install Expression Source: https://github.com/dbrattli/expression/blob/main/README.md Installs the latest version of the 'expression' library from PyPI. Requires Python 3.10 or higher. ```console pip install expression ``` -------------------------------- ### Matplotlib Setup Source: https://github.com/dbrattli/expression/blob/main/docs/notebooks.ipynb Imports necessary libraries for Matplotlib plotting, including rcParams, cycler, pyplot, and numpy. Sets up interactive mode for plotting. ```python from matplotlib import rcParams, cycler import matplotlib.pyplot as plt import numpy as np plt.ion() ``` -------------------------------- ### Eta Conversion Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/lambda_calculus.md Shows eta-conversion by demonstrating that a function applied to an argument is equivalent to the function itself, simplifying expressions. ```python # Eta-conversion # λx.(f x) and f f = lambda x: x (lambda x: f(x)) == f ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/dbrattli/expression/blob/main/README.md Installs pre-commit hooks to run code checks automatically on every commit. This ensures code quality and adherence to style guides. ```bash > pre-commit install ``` -------------------------------- ### Composable get and put using Io Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/effects.md Reimplements `get` and `put` functions using the `Io` monad, making them composable. The `put` function returns an `Io` action that prints a string, and `get` returns an `Io` action that reads input and passes it to a continuation. ```python from typing import Callable def put(string) -> Io[str]: def side_effect(_): # The actual print operation is wrapped # Io.rtn(print(string)) returns an Io action that prints and returns None # The world is incremented by Io.rtn return Io.rtn(print(string)) # Io.rtn(None) creates an initial Io action that returns None without side effects # .bind(side_effect) sequences the print action after the initial None action return Io.rtn(None).bind(side_effect) def get(fn: Callable[[str], Io[str]]) -> Io[str]: def side_effect(_): # Reads input and passes it to the provided function `fn` return fn(input()) # Creates an Io action that returns None, then binds the input reading side effect return Io.rtn(None).bind(side_effect) ``` -------------------------------- ### Chaining Io Actions Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/effects.md Demonstrates how to chain multiple `Io` actions (like `put` and `get`) using the `bind` method to create a sequence of operations that interact with the user. ```python io = put("Hello, what is your name?").bind( lambda _: get( lambda name: put("What is your age?").bind( lambda _: get( lambda age: put("Hello %s, your age is %d." % (name, int(age))) ) ) )) # Calling io and io will execute the same sequence of actions # (io, io) ``` -------------------------------- ### Basic Callback Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Demonstrates a simple callback mechanism using Python's `threading.Timer`. A `long_running` function simulates a task that completes after a delay and then calls a provided `callback` function with its result. ```python import threading def long_running(callback): def done(): result = 42 callback(result) timer = threading.Timer(5.0, done) timer.start() long_running(print) ``` -------------------------------- ### Pipelining with Expression's `pipe` Function Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Provides an example of using the `expression.pipe` function with sequence operations for a more readable data transformation pipeline. ```python from expression import pipe from expression.collections import seq xs = seq.range(10) pipe( xs, seq.map(lambda x: x * 10), seq.filter(lambda x: x > 50), seq.fold(lambda s, x: s + x, 0), ) ``` -------------------------------- ### Unix-like Pipelining Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md A conceptual example of how commands are chained together in a Unix-like shell using the pipe symbol (`|`). ```bash command_1 | command_2 | command_3 | .... | command_N ``` -------------------------------- ### Install Expression with Pydantic v2 Support Source: https://github.com/dbrattli/expression/blob/main/README.md Installs the 'expression' library with Pydantic v2 extra dependencies. Requires Python 3.10 or higher. ```console pip install expression[pydantic] ``` -------------------------------- ### Python None Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Demonstrates the use of `None` in Python to represent the absence of a value and its printing. ```python xs = None print(xs) ``` -------------------------------- ### AsyncOption Example Source: https://github.com/dbrattli/expression/blob/main/README.md Demonstrates the usage of AsyncOption for composing asynchronous operations that might return an optional value. It shows how to handle `Nothing` and short-circuit execution when no value is present. ```python from collections.abc import AsyncGenerator from expression import Nothing, Some, effect @effect.async_option[int]() async def fn_option() -> AsyncGenerator[int, int]: x: int = yield 42 # Regular value y: int = yield await Some(43) # Awaitable Some value # Short-circuit if condition is met if x + y > 80: z: int = yield await Nothing # This will short-circuit else: z: int = yield 44 yield x + y + z # Final value # This would be run in an async context # result = await fn_option() # assert result is Nothing ``` -------------------------------- ### Matplotlib Plotting Example Source: https://github.com/dbrattli/expression/blob/main/docs/notebooks.ipynb Generates a sample plot using Matplotlib with logarithmic data and custom color cycles. Demonstrates setting a random seed for reproducibility and creating a legend with custom lines. ```python # Fixing random state for reproducibility np.random.seed(19680801) N = 10 data = [np.logspace(0, 1, 100) + np.random.randn(100) + ii for ii in range(N)] data = np.array(data).T cmap = plt.cm.coolwarm rcParams['axes.prop_cycle'] = cycler(color=cmap(np.linspace(0, 1, N))) from matplotlib.lines import Line2D custom_lines = [Line2D([0], [0], color=cmap(0.), lw=4), Line2D([0], [0], color=cmap(.5), lw=4), Line2D([0], [0], color=cmap(1.), lw=4)] fig, ax = plt.subplots(figsize=(10, 5)) lines = ax.plot(data) ax.legend(custom_lines, ['Cold', 'Medium', 'Hot']); ``` -------------------------------- ### Procedural Composition Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Demonstrates a procedural approach to combining functions, where the sequence of operations is hard-coded within a single function. ```python def f(x): return x+1 def g(x): return x*2 # Procedural / imperative composition. The function `h` becomes hard-coded to `f` ang `g` def h(x): y = f(x) z = g(y) return z h(42) ``` -------------------------------- ### Closure Example (Hat Function) Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/containers.md A Python example demonstrating closures, where an inner function remembers and accesses variables from its enclosing scope. This illustrates how functions can encapsulate state, similar to objects. ```python def hat(item): def pull(): return item return pull small_hat = lambda item: lambda pull: item pull = hat("rabbit") pull() ``` -------------------------------- ### Functional Composition Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Shows a functional approach to composition in Python, where a `compose` function is used to create a new function `h` from `f` and `g`. ```python # Functional compose. Inject all dependencies. def compose(f, g): return lambda x: g(f(x)) h = compose(f, g) h(42) ``` -------------------------------- ### Beta Reduction Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/lambda_calculus.md Illustrates beta-reduction, the process of applying a function to its argument, by evaluating a simple lambda expression in Python. ```python (lambda n: n*2)(7) == 7*2 ``` -------------------------------- ### Iterator Pull Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/containers.md Demonstrates the 'pull' mechanism of iterators in Python. It shows how to obtain an iterator from a list and retrieve elements one by one using the `next()` function. ```python iterable = [1, 2, 3] iterator = iter(iterable) # get iterator value = next(iterator) print(value) value = next(iterator) print(value) value = next(iterator) print(value) # value = next(iterator) ``` -------------------------------- ### AsyncResult Example Source: https://github.com/dbrattli/expression/blob/main/README.md Demonstrates the usage of AsyncResult for composing asynchronous operations that may fail. It shows how to handle errors and short-circuit execution when an error occurs. ```python from collections.abc import AsyncGenerator from expression import Error, Ok, effect @effect.async_result[int, str]() async def fn() -> AsyncGenerator[int, int]: x: int = yield 42 # Regular value y: int = yield await Ok(43) # Awaitable Ok value # Short-circuit if condition is met if x + y > 80: z: int = yield await Error("Value too large") # This will short-circuit else: z: int = yield 44 yield x + y + z # Final value # This would be run in an async context # result = await fn() # assert result == Error("Value too large") ``` -------------------------------- ### Alpha Conversion Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/lambda_calculus.md Demonstrates alpha-conversion by showing that renaming a bound variable in a lambda expression does not change its behavior or result. ```python (lambda x: x)(42) == (lambda y: y)(42) # Renaming ``` -------------------------------- ### Using Pipe for Observable Composition Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/containers.md Illustrates how to use a `pipe` function to compose Observable operations in Python. The `pipe` function takes an initial argument and applies a series of functions to it sequentially. This example chains an `infinite` observable with a `take` operator to process the first 10 values. ```python def pipe(arg, *fns): for fn in fns: arg = fn(arg) return arg observable = pipe( infinite(), # infinite sequence of values take(10) # take the first 10 ) observable(observer) ``` -------------------------------- ### Observable Implementation with Functions Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/containers.md Demonstrates a functional implementation of an Observable pattern in Python. It includes an `observer` function to process values, an `infinite` function to generate an infinite sequence, and a `take` function to limit the number of values emitted. The example shows how to chain these functions to create a data stream. ```python import sys def observer(value): print(f"got value: {value}") def infinite(): def subscribe(obv): for x in range(1000): obv(x) return subscribe def take(count): def obs(source): def subscribe(obv): n = count def observer(value): nonlocal n if n > 0: obv(value) n -= 1 source(observer) return subscribe return obs take(10)(infinite())(observer) ``` -------------------------------- ### Option Effect with Yield Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Demonstrates using the `@effect.option` decorator to create functions that handle optional values using `yield`. The example shows yielding a value and then yielding from another Option. ```python from expression import effect, Some @effect.option[int]() def fn(): x = yield 42 y = yield from Some(43) return x + y fn() ``` -------------------------------- ### Mixing Fluent and Functional Syntax Source: https://github.com/dbrattli/expression/blob/main/README.md Illustrates how to combine the fluent (method chaining) and functional (pipe) syntaxes within the Expression library. This example shows a fluent pipe operation on a sequence. ```python from expression.collections import Seq, seq xs = Seq.of(1, 2, 3).pipe(seq.map(mapper)) ``` -------------------------------- ### Tagged Union Implementation Source: https://github.com/dbrattli/expression/blob/main/README.md Demonstrates how to define and use tagged unions in the Expression library. It includes creating data classes for union cases, decorating the main union class with `@tagged_union`, and defining optional static methods for case creation. The example also shows how to pattern match on the created tagged union. ```python from dataclasses import dataclass from typing import Literal from expression import case, tag, tagged_union @dataclass class Rectangle: width: float length: float @dataclass class Circle: radius: float @tagged_union class Shape: tag: Literal["rectangle", "circle"] = tag() rectangle: Rectangle = case() circle: Circle = case() @staticmethod def Rectangle(width: float, length: float) -> "Shape": """Optional static method for creating a tagged union case""" return Shape(rectangle=Rectangle(width, length)) @staticmethod def Circle(radius: float) -> "Shape": """Optional static method for creating a tagged union case""" return Shape(circle=Circle(radius)) ``` ```python shape = Shape.Rectangle(2.3, 3.3) match shape: case Shape(tag="rectangle", rectangle=Rectangle(width=2.3)): assert shape.rectangle.width == 2.3 case _: assert False ``` -------------------------------- ### Python Type Checking Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Demonstrates a Python function `run` that concatenates a string and an integer, which would typically cause a runtime type error. It highlights the need for static type checkers. ```python def run(): return "abc" + 10 ``` ```python run() ``` -------------------------------- ### Expression vs. F# Module and Type Naming Source: https://github.com/dbrattli/expression/blob/main/README.md Illustrates the difference in naming conventions between Expression and F# for modules and types. In F#, modules are capitalized, while in Expression, modules are lowercase (following PEP-8) and types are capitalized. This example shows how to import and differentiate between the `option` module and the `Option` type in Expression. ```python from expression import Option, option print(Option) print(option) ``` -------------------------------- ### Create Card Instances Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/data_modelling.md Demonstrates the creation of different `Card` instances using the static factory methods defined in the `Card` tagged union. ```python jack_of_hearts = Card.Face(suit=Suit.Hearts(), face=Face.Jack()) three_of_clubs = Card.Value(suit=Suit.Clubs(), value=3) joker = Card.Joker() ``` -------------------------------- ### Expression Library Some Constructor Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Demonstrates creating an `Option` value using the `Some` constructor with an integer value and printing it. ```python from expression import Some xs = Some(42) print(xs) ``` -------------------------------- ### Async/Await Pythagoras using Cont Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Demonstrates how the `Cont` class, with `__await__` implemented, enables the use of `async`/`await` syntax for the `pythagoras` calculation. This mirrors the structure of asynchronous programming. ```python import math def add(a, b): return Cont.rtn(a + b) def square(x): return Cont.rtn(x * x) def sqrt(x): return Cont.rtn(math.sqrt(x)) async def pythagoras(a, b): aa = await square(a) bb = await square(b) aabb = await add(aa, bb) ab = await sqrt(aabb) return ab # Note: To run this, you would typically need an async context: # import asyncio # result = await pythagoras(2,3) # print(result) ``` -------------------------------- ### Nested AsyncResult Example Source: https://github.com/dbrattli/expression/blob/main/README.md Illustrates how AsyncResult can be nested, allowing for the composition of multiple asynchronous operations where each operation might fail. This example shows an outer function calling an inner asynchronous function that also uses AsyncResult. ```python @effect.async_result[int, str]() async def inner(x: int) -> AsyncGenerator[int, int]: y: int = yield x + 1 yield y + 1 # Final value is y + 1 @effect.async_result[int, str]() async def outer() -> AsyncGenerator[int, int]: x: int = yield 40 # Call inner and await its result inner_result = await inner(x) y: int = yield await inner_result yield y # Final value is y # This would be run in an async context # result = await outer() # assert result == Ok(42) # 40 -> 41 -> 42 ``` -------------------------------- ### Nested AsyncOption Example Source: https://github.com/dbrattli/expression/blob/main/README.md Illustrates nesting of AsyncOption, enabling the composition of multiple asynchronous operations that may return optional values. This example shows an outer function calling an inner asynchronous function that also uses AsyncOption. ```python @effect.async_option[int]() async def inner_option(x: int) -> AsyncGenerator[int, int]: y: int = yield x + 1 yield y + 1 # Final value is y + 1 @effect.async_option[int]() async def outer_option() -> AsyncGenerator[int, int]: x: int = yield 40 # Call inner and await its result inner_result = await inner_option(x) y: int = yield await inner_result yield y # Final value is y # This would be run in an async context # result = await outer_option() # assert result == Some(42) # 40 -> 41 -> 42 ``` -------------------------------- ### Using Pipeline for Fetch and Parse Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/railway.md Demonstrates how to create a `fetch_and_parse` function by composing `fetch` and `parse` functions using the previously defined pipeline. ```python fetch_and_parse = pipeline(fetch, parse) result = fetch_and_parse("http://123") print(result) ``` -------------------------------- ### Running an Io Action Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/effects.md Shows how to execute a composed `Io` action using the `run` method. The `world` parameter represents the state that is threaded through the sequence of effects. ```python io.run(world=0) ``` -------------------------------- ### Dynamic Function Creation with eval Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Demonstrates creating a function dynamically using `eval`. This method is generally discouraged due to security risks. ```python add_10 = eval("lambda x: x+10") add_10(20) ``` -------------------------------- ### Initialize MyST Markdown for Jupyter Book Source: https://github.com/dbrattli/expression/blob/main/docs/markdown-notebooks.md A command-line utility to quickly add the necessary YAML metadata to a markdown file, enabling Jupyter Book to treat it as a MyST Markdown Notebook. This facilitates the conversion of text files into executable notebooks. ```bash jupyter-book myst init path/to/markdownfile.md ``` -------------------------------- ### Python Dictionary Get None Value Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Shows how `dict.get()` returns `None` when a key is missing or its value is explicitly `None` in a Python dictionary. ```python mapping = dict(a=None) mapping.get("a") ``` -------------------------------- ### Expression Library Nothing Singleton Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Shows how to use the `Nothing` singleton from the `expression` library to represent the absence of a value and prints it. ```python from expression import Nothing xs = Nothing print(xs) ``` -------------------------------- ### Synchronous Pythagoras Calculation Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Illustrates a standard functional approach to calculating the hypotenuse of a right triangle using separate functions for addition, squaring, and square root. This serves as a baseline before introducing CPS. ```python import math def add(a, b): return a + b def square(x): return x * x def sqrt(x): return math.sqrt(x) def pythagoras(a, b): return sqrt(add(square(a), square(b))) ``` -------------------------------- ### Composing Fetch and Parse with Bind Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/railway.md Demonstrates composing the `fetch` and `parse` functions using the `bind` method. This approach is more concise and functional, handling the propagation of errors automatically. ```python result = bind(parse, fetch("http://42")) print(result) ``` -------------------------------- ### Re-demonstrating Generic Compose Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/railway.md A repeat of the generic compose function for clarity, showing how to create a composed function `fetch_parse` from `fetch` and `parse`. ```python def compose(f, g): return lambda x: f(x).bind(g) fetch_parse = compose(fetch, parse) result = fetch_parse("http://42") print(result) ``` -------------------------------- ### Pipelining with Expression Sequence Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Illustrates the use of the `pipe` function and sequence operations (`seq.map`, `seq.filter`) for creating data processing pipelines. ```python from expression import pipe from expression.collections import seq xs = seq.of_iterable(range(10)) mapping = seq.map(lambda x: x * 10) filter = seq.filter(lambda x: x > 30) pipe(xs, mapping, filter, list, ) ``` -------------------------------- ### Try Module Documentation Source: https://github.com/dbrattli/expression/blob/main/docs/reference/try.md Provides documentation for the 'expression.core.try_' module, including its members and inheritance hierarchy. This is generated using automodule from the Sphinx documentation generator. ```python .. automodule:: expression.core.try_ :members: :show-inheritance: ``` -------------------------------- ### Side Effect Functions (get/put) Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/effects.md Defines abstract `get` and `put` functions that represent operations with side-effects. These are initially presented as non-composable due to their interaction with the external world (input/output). ```python def get() -> str: ... def put(text: str) -> None: ... ``` -------------------------------- ### MyST Markdown Inline Role Source: https://github.com/dbrattli/expression/blob/main/docs/markdown.md Shows an example of an inline role in MyST Markdown, specifically a '{doc}' role used to refer to another document. Roles are written in a single line. ```markdown {doc}`markdown-notebooks` ``` -------------------------------- ### Expression Library Effect Handling (Option) Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/effects.md Illustrates how the `expression` library's `@effect.option` decorator simplifies working with `Option` types, allowing for generator-style syntax to handle potential `Nothing` values gracefully. ```python from expression import effect, Option, Some, Nothing def divide(a: float, divisor: float) -> Option[float]: try: return Some(a / divisor) except ZeroDivisionError: return Nothing @effect.option[float]() def comp(x: float): # 'yield from' unwraps the Option, returning Nothing if divide fails result: float = yield from divide(42, x) result += 32 print(f"The result is {result}") return result # Calling comp(42) will return Some(74.0) and print the result # Calling comp(0) will return Nothing without printing comp(42) ``` -------------------------------- ### Import Necessary Types Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/data_modelling.md Imports core components from the expression library and standard Python typing modules for data modelling. ```python from __future__ import annotations from dataclasses import dataclass from typing import Generic, Tuple, TypeVar, final from expression import case, tag, tagged_union _T = TypeVar("_T") ``` -------------------------------- ### Expression Library Testing for Nothing Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Illustrates how to test if an `Option` value is `Nothing` using the `is` operator. ```python xs = Nothing assert xs is Nothing ``` -------------------------------- ### Pipeline Option Module Source: https://github.com/dbrattli/expression/blob/main/docs/reference/pipeline.md Provides documentation for the pipeline option module. This automodule directive lists all members of the specified module, offering insights into the pipeline's configuration and option-related functionalities. ```python expression.extra.option.pipeline ``` -------------------------------- ### Referential Transparency Example Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/effects.md Demonstrates a Python function that modifies a mutable object (a list) captured from an outer scope, illustrating a violation of referential transparency. It highlights the potential for unexpected behavior when such functions are called multiple times. ```python z = [42] def expr(a): #return a + 1 a += int(input()) return a #print(a) #z[0] += a #return z[0] ``` -------------------------------- ### Result Type: Handling Success and Errors Source: https://github.com/dbrattli/expression/blob/main/README.md Introduces the `Result` type for error-tolerant code. The `@effect.result` decorator allows coroutines to yield `Ok` or `Error` values. This example shows a successful computation returning `Ok(52)`. ```python from expression import Ok, Result, effect @effect.result[int, Exception]() def fn5() -> Generator[int, int, int]: x = yield from Ok(42) y = yield from Ok(10) return x + y xs = fn5() assert isinstance(xs, Result) ``` -------------------------------- ### Expression Library Import Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Imports the necessary components (`Option`, `option`, `Some`, `Nothing`) from the `expression` library for working with optional values. ```python from expression import Option, option, Some, Nothing ``` -------------------------------- ### Call Option Returning Function Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Shows how to call a function that returns an Option type and the expected output for positive and negative inputs. ```python keep_positive(42) ``` ```python keep_positive(-1) ``` -------------------------------- ### Python Testing for None Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Demonstrates how to test for `None` and non-`None` values using `is None` and `is not None` assertions in Python. ```python xs = None assert xs is None y = 42 assert y is not None ``` -------------------------------- ### Secure Password with Single Case Tagged Union Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/data_modelling.md This Python code snippet demonstrates the creation of a single case tagged union for a secure password. It uses the 'tagged_union' decorator and overrides string representation methods to prevent password leakage in logs or console output. The example includes creating an instance and pattern matching to verify its functionality. ```python @tagged_union(frozen=True, repr=False) class SecurePassword: password: str = case() # Override __str__ and __repr__ to make sure we don't leak the password in logs def __str__(self) -> str: return "********" def __repr__(self) -> str: return "SecurePassword(password='********')" password = SecurePassword(password="secret") match password: case SecurePassword(password=p): assert p == "secret" ``` -------------------------------- ### Monadic Pythagoras Execution Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Executes the `pythagoras` computation wrapped in the `Cont` class and prints the final result. ```python result = pythagoras(2, 3) result.run(print) ``` -------------------------------- ### Monad Protocol Definition Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Defines the Monad protocol in Python using `typing_extensions.Protocol` and `abc.abstractmethod`. This serves as a blueprint for Monad implementations, requiring `rtn` and `then` methods. ```python from typing_extensions import Protocol, runtime_checkable from abc import abstractmethod @runtime_checkable class Monad(Protocol): @staticmethod @abstractmethod def rtn(a): raise NotImplementedError @abstractmethod def then(self, fn): raise NotImplementedError ``` -------------------------------- ### Chaining Bind Operations Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/railway.md Illustrates how to chain multiple `bind` operations to perform sequential computations, such as fetching and parsing data multiple times. This avoids the 'Pyramid of Doom' associated with nested callbacks. ```python from expression.core import result result = bind(parse, bind(lambda x: fetch("http://%s" % x), bind(lambda x: fetch("http://%s" % x), bind(lambda x: fetch("http://%s" % x), bind(lambda x: fetch("http://%s" % x), bind(lambda x: fetch("http://%s" % x), bind(lambda x: fetch("http://%s" % x), fetch("http://123") ) ) ) ) ) ) ) print(result) ``` -------------------------------- ### Fetch and Parse Composition (Imperative) Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/railway.md Demonstrates an imperative approach to composing the `fetch` and `parse` functions. It manually checks the Result type and extracts values, highlighting the verbosity and potential for errors. ```python def fetch_parse(url): b = fetch(url) if isinstance(b, Ok): val_b = b._value # <--- Don't look inside the box!!! return parse(val_b) else: # Must be error return b result = fetch_parse("http://42") print(result) ``` -------------------------------- ### Basic Function Definition and Usage Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Demonstrates the definition and usage of a simple Python function that adds two numbers. ```python def add(a, b): return a + b add(10, 20) ``` -------------------------------- ### Expression Block Usage Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/containers.md Demonstrates the creation and manipulation of an immutable list (Block) from the Expression library. Shows how to create a Block from a sequence and perform operations like cons (add to front) and tail (remove first element). ```python from expression.collections import Block xs = Block.of_seq(range(10)) print(xs) ys = xs.cons(10) print(ys) zs = xs.tail() print(zs) ``` -------------------------------- ### Point-Free Programming with Reduce Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/lambda_calculus.md Demonstrates point-free programming style using Python's `functools.reduce` to find the maximum value in a range, comparing a lambda-based approach with a direct function reference. ```python from functools import reduce xs = reduce(lambda acc, x: max(acc, x), range(10)) print(xs) xs = reduce(max, range(10)) print(xs) ``` -------------------------------- ### Expression Map Usage Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/containers.md Illustrates the use of the immutable dictionary (Map) from the Expression library. Shows how to create a Map from a sequence of key-value pairs and filter its contents based on a condition. ```python from expression.collections import Map items = dict(a=10, b=20).items() xs = Map.of_seq(items) print(xs) ys = xs.filter(lambda k, v: v>10) print(ys) ``` -------------------------------- ### Curried Addition with Expression Decorator Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Shows how to use the `@curry` decorator from the Expression library to achieve currying for a function with multiple arguments. ```python from expression import curry @curry(1) def add(a: int, b: int) -> int: return a + b add(3)(4) ``` -------------------------------- ### Synchronous Pythagoras Execution Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Executes the synchronous `pythagoras` function and prints its result. This snippet is used to demonstrate the output of the non-CPS version. ```python result = pythagoras(2,3) print(result) ``` -------------------------------- ### Cont Monad with Asyncio Support Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Extends the `Cont` class to support Python's `asyncio` by implementing the `__await__` method. This allows `Cont` computations to be used with `async` and `await` syntax. ```python import asyncio class Cont: def __init__(self, cps): self.__cps = cps # fn: ('a -> 'r) -> 'r @staticmethod def rtn(a): return Cont(lambda cont: cont(a)) def run(self, cont): self.__cps(cont) def __await__(self): loop = asyncio.get_event_loop() future = loop.create_future() def done(value): future.set_result(value) self.run(done) return iter(future) def then(self, fn): # Cont <| fun c -> run cont (fun a -> run (fn a) c ) return Cont(lambda c: self.run(lambda a: (fn(a).run(c)))) ``` -------------------------------- ### Pipelining with the pipe function Source: https://github.com/dbrattli/expression/blob/main/README.md Demonstrates how to use the `pipe` function to create workflows by passing a value through multiple functions. This is a core feature for building pipelines. ```python from collections.abc import Callable from expression import pipe v = 1 fn1: Callable[[int], int] = lambda x: x + 1 gn1: Callable[[int], int] = lambda x: x * 2 assert pipe(v, fn1, gn1) == gn1(fn1(v)) ``` -------------------------------- ### Python Optional Type Hint Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Shows how to use Python's `typing.Optional` to hint that a variable can hold an integer or `None`, and prints its value. ```python from typing import Optional xs: Optional[int] = None print(xs) ``` -------------------------------- ### Pipe Module Documentation Source: https://github.com/dbrattli/expression/blob/main/docs/reference/pipe.md Provides detailed documentation for the expression.core.pipe module, including all its members and their functionalities. ```APIDOC .. automodule:: expression.core.pipe :members: ``` -------------------------------- ### Pipelining with Expression objects' pipe method Source: https://github.com/dbrattli/expression/blob/main/README.md Shows how to use the `pipe` method directly on Expression objects like `Some` for dot-chaining pipelines. This allows for a more object-oriented approach to pipelining. ```python from expression import Option, Some v = Some(1) fn2: Callable[[Option[int]], Option[int]] = lambda x: x.map(lambda y: y + 1) gn2: Callable[[Option[int]], Option[int]] = lambda x: x.map(lambda y: y * 2) assert v.pipe(fn2, gn2) == gn2(fn2(v)) ``` -------------------------------- ### Safe Division with Option Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Illustrates creating a pure function for division that returns an Option, handling ZeroDivisionError by returning Nothing instead of raising an exception. ```python from expression import Some, Nothing def divide(a: float, divisor: float) -> Option[int]: try: return Some(a/divisor) except ZeroDivisionError: return Nothing ``` -------------------------------- ### CPS Pythagoras Execution Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Executes the CPS version of the `pythagoras` function, passing `print` as the final continuation to display the result. ```python pythagoras(2, 3, print) ``` -------------------------------- ### Functional Syntax with Pipe Source: https://github.com/dbrattli/expression/blob/main/README.md Demonstrates the functional syntax using the `pipe` function for chaining operations like map and filter on a sequence. It shows how to transform and aggregate data in a functional style. ```python from expression import pipe from expression.collections import Seq, seq mapper: Callable[[int], int] = lambda x: x * 100 xs = Seq.of(1, 2, 3) ys = pipe( xs, seq.map(mapper), seq.filter(lambda x: x > 100), seq.fold(lambda s, x: s + x, 0), ) ``` -------------------------------- ### Map Nothing Value Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/optional_values.md Illustrates that applying `map` to a `Nothing` Option results in `Nothing`, demonstrating the 'nothing in, nothing out' principle. ```python from expression import Some, option, pipe, Nothing xs = Nothing ys = pipe( xs, option.map(lambda x: x*10) ) print(ys) ``` -------------------------------- ### Compact List out of Lambda (LOL) Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/containers.md A more concise implementation of the List out of Lambda (LOL) pattern using lambda functions. This version provides the same list functionality (prepend, head, tail, is_empty) with shorter syntax. ```python empty_list = None prepend = lambda el, lst: lambda selector: selector(el, lst) head = lambda lst: lst(lambda h, t: h) tail = lambda lst: lst(lambda h, t: t) is_empty = lambda lst: lst is empty_list a = prepend("a", prepend("b", empty_list)) assert("a" == head(a)) assert("b" == head(tail(a))) assert(tail(tail(a))==empty_list) assert(not is_empty(a)) assert(is_empty(empty_list)) print("all tests are green!") ``` -------------------------------- ### Monadic Pythagoras with Cont Class Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/continuations.md Implements the `pythagoras` calculation using the `Cont` class. Operations like `add`, `square`, and `sqrt` now return `Cont` objects, and computations are chained using the `then` method. ```python import math def add(a, b): return Cont.rtn(a + b) def square(x): return Cont.rtn(x * x) def sqrt(x): return Cont.rtn(math.sqrt(x)) def pythagoras(a, b): return square(a).then( lambda aa: square(b).then( lambda bb: add(aa, bb).then( lambda aabb: sqrt(aabb) ) ) ) ``` -------------------------------- ### Python Function Composition Source: https://github.com/dbrattli/expression/blob/main/docs/tutorial/introduction.md Provides a Python implementation of a `compose` function that chains two functions together, returning a new function. ```python # Python define compose(f: Callable[[A], B], g: Callable[[B], C]) -> Callable[[A], C]: return lambda x: g(f(x)) ```