def __init__(self, source: Iterable, init: List[A] = List(), chunk_size: Union[int, None] = None) -> None: self.source = iter(source) self.strict = init self._chunk_size = chunk_size or self._default_chunk_size
def import_path(path: str) -> 'Either[ImportFailure, B]': from amino.list import List return ( List.wrap(path.rsplit('.', 1)) .lift_all(0, 1) .to_either(InvalidLocator(f'invalid module path: {path}')) .flat_map2(lambda a, b: Either.import_name(a, b).lmap(lambda a: ImportException(path, a))) )
def flat_map(self, fa: LazyList[A], f: Callable[[A], LazyList[B]]) -> LazyList[B]: a, b = itertools.tee(fa.source) fa.source = a strict_m = fa.strict.map(f) lazy_m = map(f, b) mapped = itertools.chain(strict_m, lazy_m) source = itertools.chain.from_iterable(mapped) return LazyList(source, List(), fa._chunk_size)
def product_n(self, num: int, fa: F, *fs: Iterable[F]): from amino.list import List if len(fs) != num: msg = 'passed {} args to {}.product{}' name = self.__class__.__name__ raise TypeError(msg.format(len(fs), name, num)) def add(a, b): return self.flat_map(a, lambda a: self.map(b, lambda b: a + (b,))) init = self.map(fa, lambda a: (a,)) return List.wrap(fs).fold_left(init)(add)
def effs(self, fa: F, *args): from amino.eff import Eff types = List.wrap(args) c = lambda a, b: Eff(fa, a, depth=b) with_depth = lambda d, t: c(t, d) types_only = lambda: c(types, depth=len(types)) def try_depth(h, t): return with_depth(int(h), t) if isinstance(h, int) else types_only() return types.detach_head.map2(try_depth) | types_only
def _drain_find(self, abort: Callable[[A], bool]) -> Maybe[A]: culprit = Empty() def gen() -> Generator: nonlocal culprit while True: try: el = next(self.source) yield el if abort(el): culprit = Just(el) break except StopIteration: break drained = List.wrap(list(gen())) self.strict = self.strict + drained return culprit
def flat_map(self, f: Callable[[A, B], Maybe[Tuple[C, D]]]) -> 'Map[C, D]': filtered = List.wrap([f(a, b) for a, b in self.items()])\ .join return Map(filtered)
def to_list(self): from amino.list import List return self.cata(lambda v: List(v), List())
def format_cause(exc: Exception, **kw) -> List[str]: from amino import Maybe return Maybe(exc.__cause__) / (lambda a: format_exception(a, **kw)) / (lambda a: a.cons('Cause:')) | List()
def append(self, other: 'LazyList[A]') -> 'LazyList[A]': return self.copy( lambda s: concatv(s, self.strict, other.source, other.strict), lambda s: List())
def pure(self, a: A): return LazyList([], List(a))
def map2(self, f: Callable[[A, B], C]) -> List[C]: return List.wrap([f(a, b) for a, b in self.items()])
def eff(self, fa: F, tpe: type = None): from amino.eff import Eff tpes = List() if tpe is None else List(tpe) return Eff(fa, tpes, 1)
def get_all_map(self, *keys): def append(zm, k): return zm // (lambda z: self.get_item(k) / z.cat) return List.wrap(keys).fold_left(Just(Map()))(append)
def values_at(self, *keys): return List.wrap(keys) // self.get
def k(self): return List(*Dict.keys(self))
def to_list(self): return List.wrap(self.items())