diff options
author | crupest <crupest@outlook.com> | 2024-11-11 01:12:29 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2024-12-18 18:31:27 +0800 |
commit | 95da3ade5bfa6ef39923cd3fc2a551ad983c1537 (patch) | |
tree | d2bf4e40bf625c75768d5ccda2ca49dbaba97a9a /tools/cru-py/cru/util/_func.py | |
parent | eff33fcbc8e78b1cd15332c229cd39ae9befbe5e (diff) | |
download | crupest-95da3ade5bfa6ef39923cd3fc2a551ad983c1537.tar.gz crupest-95da3ade5bfa6ef39923cd3fc2a551ad983c1537.tar.bz2 crupest-95da3ade5bfa6ef39923cd3fc2a551ad983c1537.zip |
HALF WORK: 2024.11.12
Diffstat (limited to 'tools/cru-py/cru/util/_func.py')
-rw-r--r-- | tools/cru-py/cru/util/_func.py | 122 |
1 files changed, 55 insertions, 67 deletions
diff --git a/tools/cru-py/cru/util/_func.py b/tools/cru-py/cru/util/_func.py index 3221c94..d9f8044 100644 --- a/tools/cru-py/cru/util/_func.py +++ b/tools/cru-py/cru/util/_func.py @@ -1,16 +1,14 @@ from collections.abc import Callable -from typing import TypeVar, Any, ParamSpec +from typing import TypeVar +from ._cru import CRU from ._const import CRU_PLACEHOLDER T = TypeVar("T") -R = TypeVar("R") -R1 = TypeVar("R1") -P = ParamSpec("P") -P1 = ParamSpec("P1") +_PLACEHOLDER = CRU_PLACEHOLDER -class RawFunctions: +class CruRawFunctions: @staticmethod def none(*_v, **_kwargs) -> None: return None @@ -28,15 +26,15 @@ class RawFunctions: return v @staticmethod - def only_you(r: T, *_v, **_kwargs) -> T: - return r + def only_you(v: T, *_v, **_kwargs) -> T: + return v @staticmethod - def equal(a: Any, b: Any) -> bool: + def equal(a, b) -> bool: return a == b @staticmethod - def not_equal(a: Any, b: Any) -> bool: + def not_equal(a, b) -> bool: return a != b @staticmethod @@ -44,95 +42,85 @@ class RawFunctions: return not v -class MetaFunction: +class CruFunctionMeta: @staticmethod - def bind(f: Callable[P, R], *bind_args, **bind_kwargs) -> Callable[P1, R1]: - def bound(*args, **kwargs): + def bind(func: Callable, *bind_args, **bind_kwargs) -> Callable: + def bound_func(*args, **kwargs): popped = 0 real_args = [] - for a in bind_args: - if a is CRU_PLACEHOLDER: + for arg in bind_args: + if arg is _PLACEHOLDER: real_args.append(args[popped]) popped += 1 else: - real_args.append(a) + real_args.append(arg) real_args.extend(args[popped:]) - return f(*real_args, **(bind_kwargs | kwargs)) + return func(*real_args, **(bind_kwargs | kwargs)) - return bound + return bound_func @staticmethod - def chain(*fs: Callable) -> Callable: - if len(fs) == 0: + def chain(*funcs: Callable) -> Callable: + if len(funcs) == 0: raise ValueError("At least one function is required!") - rf = fs[0] - for f in fs[1:]: - def n(*args, **kwargs): - r = rf(*args, **kwargs) - r = r if isinstance(r, tuple) else (r,) - return f(*r) - rf = n - return rf + final_func = funcs[0] + for func in funcs[1:]: + func_copy = func - @staticmethod - def chain_single(f: Callable[P, R], f1: Callable[P1, R1], *bind_args, **bind_kwargs) -> \ - Callable[ - P, R1]: - return MetaFunction.chain(f, MetaFunction.bind(f1, *bind_args, **bind_kwargs)) + def chained_func(*args, **kwargs): + results = final_func(*args, **kwargs) + results = results if isinstance(results, tuple) else (results,) + return func_copy(*results) - convert_r = chain_single + final_func = chained_func - @staticmethod - def neg(f: Callable[P, bool]) -> Callable[P, bool]: - return MetaFunction.convert_r(f, RawFunctions.not_) + return final_func # Advanced Function Wrapper class CruFunction: - def __init__(self, f): + def __init__(self, f: Callable): self._f = f @property def f(self) -> Callable: return self._f + @property + def func(self) -> Callable: + return self.f + def bind(self, *bind_args, **bind_kwargs) -> "CruFunction": - self._f = MetaFunction.bind(self._f, *bind_args, **bind_kwargs) + self._f = CruFunctionMeta.bind(self._f, *bind_args, **bind_kwargs) return self - def chain(self, *fs: Callable) -> "CruFunction": - self._f = MetaFunction.chain(self._f, *fs) + def chain(self, *funcs: Callable) -> "CruFunction": + self._f = CruFunctionMeta.chain(self._f, *funcs) return self - def chain_single(self, f: Callable[P, R], f1: Callable[P1, R1], *bind_args, - **bind_kwargs) -> "CruFunction": - self._f = MetaFunction.chain_single(self._f, f, f1, *bind_args, **bind_kwargs) - return self + def __call__(self, *args, **kwargs): + return self._f(*args, **kwargs) - def convert_r(self, f: Callable[P, R], f1: Callable[P1, R1], *bind_args, - **bind_kwargs) -> "CruFunction": - self._f = MetaFunction.convert_r(self._f, f, f1, *bind_args, **bind_kwargs) - return self + @staticmethod + def make_chain(base_func: Callable, *funcs: Callable) -> "CruFunction": + return CruFunction(base_func).chain(*funcs) - def neg(self) -> "CruFunction": - self._f = MetaFunction.neg(self._f) - return self - def __call__(self, *args, **kwargs): - return self._f(*args, **kwargs) +class CruWrappedFunctions: + none = CruFunction(CruRawFunctions.none) + true = CruFunction(CruRawFunctions.true) + false = CruFunction(CruRawFunctions.false) + identity = CruFunction(CruRawFunctions.identity) + only_you = CruFunction(CruRawFunctions.only_you) + equal = CruFunction(CruRawFunctions.equal) + not_equal = CruFunction(CruRawFunctions.not_equal) + not_ = CruFunction(CruRawFunctions.not_) + +class CruFunctionGenerators: @staticmethod - def make_chain(*fs: Callable) -> Callable[P, R1]: - return CruFunction(MetaFunction.chain(*fs)) - - -class WrappedFunctions: - none = CruFunction(RawFunctions.none) - true = CruFunction(RawFunctions.true) - false = CruFunction(RawFunctions.false) - identity = CruFunction(RawFunctions.identity) - only_you = CruFunction(RawFunctions.only_you) - equal = CruFunction(RawFunctions.equal) - not_equal = CruFunction(RawFunctions.not_equal) - not_ = CruFunction(RawFunctions.not_) + def make_isinstance_of_types(*types: type) -> Callable: + return CruFunction(lambda v: type(v) in types) + +CRU.add_objects(CruRawFunctions, CruFunctionMeta, CruFunction, CruWrappedFunctions, CruFunctionGenerators) |