Source code for redex.combinator._fold

"""The folding combinator."""

import operator
from functools import reduce
from typing import Any, Callable
from redex.function import Signature
from redex.stack import stackmethod, verify_stack_size, Stack
from redex.combinator._base import Combinator

BinaryOperator = Callable[[Any, Any], Any]

# pylint: disable=too-few-public-methods
[docs]class Foldl(Combinator): """The left folding combinator.""" func: BinaryOperator """a function of two arguments.""" @stackmethod def __call__(self, stack: Stack) -> Stack: verify_stack_size(self, stack, self.signature) n_in = self.signature.n_in result = reduce(self.func, stack[:n_in]) # type: ignore return (result, *stack[n_in:])
[docs]def foldl(func: BinaryOperator, n_in: int = 2) -> Foldl: """Creates a left folding combinator.""" return Foldl(func=func, signature=Signature(n_in=n_in, n_out=1))
[docs]def add(n_in: int = 2) -> Foldl: """Creates an addition combinator. >>> from redex import combinator as cb >>> add = cb.add() >>> add(4, 2) == 6 True Args: n_in: a number of inputs. Returns: a combinator. """ return foldl(func=operator.add, n_in=n_in)
[docs]def sub(n_in: int = 2) -> Foldl: """Creates an subtraction combinator. >>> from redex import combinator as cb >>> sub = cb.sub() >>> sub(4, 2) == 2 True Args: n_in: a number of inputs. Returns: a combinator. """ return foldl(func=operator.sub, n_in=n_in)
[docs]def mul(n_in: int = 2) -> Foldl: """Creates a multiplication combinator. >>> from redex import combinator as cb >>> mul = cb.mul() >>> mul(4, 2) == 8 True Args: n_in: a number of inputs. Returns: a combinator. """ return foldl(func=operator.mul, n_in=n_in)
[docs]def div(n_in: int = 2) -> Foldl: """Creates a division combinator. >>> from redex import combinator as cb >>> div = cb.div() >>> div(4, 2) == 2 True Args: n_in: a number of inputs. Returns: a combinator. """ return foldl(func=operator.truediv, n_in=n_in)
fold = foldl