aboutsummaryrefslogtreecommitdiff
"""Tools to help with a more functional way of doing things."""
from typing import Iterable
from functools import reduce

def take(iterable: Iterable, num: int) -> list:
    """Take at most `num` items from `iterable`."""
    iterator = iter(iterable)
    items = []
    try:
        for i in range(0, num): # pylint: disable=[unused-variable]
            items.append(next(iterator))

        return items
    except StopIteration:
        return items

def chain(value, *functions):
    """
    Flatten nested expressions

    Inspired by, and approximates, Clojure's `->`.

    Useful to rewrite nested expressions like func3(a, b, func2(c, func1(d e)))
    into arguably flatter expressions like:
    chain(
      d,
      partial(func1, e=val1),
      partial(func2, c=val2),
      partial(func3, a=val3, b=val3))

    This can probably be improved.
    """
    return reduce(lambda result, func: func(result), functions, value)