mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 02:39:20 +00:00
104 lines
3.2 KiB
Python
104 lines
3.2 KiB
Python
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
|
|
from _erg_result import is_ok
|
|
from _erg_result import Error
|
|
|
|
class Array(list):
|
|
def try_new(arr): # -> Result[Array]
|
|
if isinstance(arr, list):
|
|
return Array(arr)
|
|
else:
|
|
return Error("not a list")
|
|
|
|
def generic_try_new(arr, cls = None): # -> Result[Array]
|
|
if cls is None:
|
|
return Array.try_new(arr)
|
|
else:
|
|
elem_t = cls.__args__[0]
|
|
elems = []
|
|
for elem in arr:
|
|
# TODO: nested check
|
|
elem = elem_t.try_new(elem)
|
|
if is_ok(elem):
|
|
elems.append(elem)
|
|
else:
|
|
return Error("not a " + str(elem_t))
|
|
return Array(elems)
|
|
|
|
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 __hash__(self):
|
|
return hash(tuple(self))
|
|
|
|
def update(self, f):
|
|
self = Array(f(self))
|
|
|
|
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 isinstance(t, set):
|
|
return self in t
|
|
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])
|
|
|
|
class UnsizedArray:
|
|
elem: object
|
|
def __init__(self, elem):
|
|
self.elem = elem
|