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 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 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 to_list(self): return List.wrap(self.items())
def map2(self, f: Callable[[A, B], C]) -> List[C]: return List.wrap([f(a, b) for a, b in self.items()])