from _erg_control import then__ from _erg_range import Range from _erg_nat import NatMut from _erg_int import IntMut from _erg_contains_operator import contains_operator class Array(list): def try_new(arr): # -> Result[Array] if isinstance(arr, list): return Array(arr) else: return Error("not a list") def dedup(self, same_bucket=None): if same_bucket is None: return Array(list(set(self))) else: removes = [] for lhs, rhs in zip(self, self[1:]): if same_bucket(lhs, rhs): removes.append(lhs) for remove in removes: self.remove(remove) return self def get(self, index, default=None): try: return self[index] except IndexError: return default def push(self, value): self.append(value) return self def partition(self, f): return Array(list(filter(f, self))), Array( list(filter(lambda x: not f(x), self)) ) def __mul__(self, n): return then__(list.__mul__(self, n), Array) def __getitem__(self, index_or_slice): if isinstance(index_or_slice, slice): return Array(list.__getitem__(self, index_or_slice)) elif isinstance(index_or_slice, NatMut) or isinstance(index_or_slice, IntMut): return list.__getitem__(self, int(index_or_slice)) elif isinstance(index_or_slice, Range): return Array(list.__getitem__(self, index_or_slice.into_slice())) else: return list.__getitem__(self, index_or_slice) def type_check(self, t: type) -> bool: if isinstance(t, list): if len(t) < len(self): return False for (inner_t, elem) in zip(t, self): if not contains_operator(inner_t, elem): return False return True elif not hasattr(t, "__args__"): return isinstance(self, t) elem_t = t.__args__[0] l = None if len(t.__args__) != 2 else t.__args__[1] if l is not None and l != len(self): return False for elem in self: if not contains_operator(elem_t, elem): return False return True def update_nth(self, index, f): self[index] = f(self[index])