-
|
Is there any way to express these function signatures using the power of Beartype? def _nat_to_kcomb(
x: Natural,
k: Natural
) -> FixedSizeSet[Natural, k]: # FIXME illegal
...
def _kcomb_to_nat(
s: Set[Natural]
) -> Natural:
...
def _nat_to_nbag(
x: Natural,
n: Natural
) -> 'Collection[NaturalLessThan[n]]: # FIXME illegal
...
def _nbag_to_nat(
ms: Collection[NaturalLessThan[n]], # FIXME illegal
n: Natural
) -> Natural:
...I'm able to construct one of the 3 types needed for this, since it's not really dependent, but the other types, I just can't figure out how to wrap my head around describing in a machine-readable way: Natural = Annotated[int, beartype.vale.Is[lambda _: (0 <= _)]] # OK
NaturalLessThan[Literal[N]] = Annotated[int, beartype.vale.Is[lambda _: (0 <= _ < N)]] # FIXME illegal
FixedSizeSet[T, Literal[K]] = Annotated[Set[T], beartype.vale.Is[lambda _: (len(_) == K)]] # FIXME illegal |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
|
Tally-ho! Indeed, fellow @beartype hacker-master @iamrecursion has been politely begging for dependent typing for years now. Someday, @beartype hopes to make this happen for everybody. Sadly, this is not that day. I (more or less) know exactly what to do in the @beartype codebase. I just lack the time and the iron will to make this happen at the moment. Thus, I weep. 😭 |
Beta Was this translation helpful? Give feedback.
-
|
...heh. Real-world syntax, huh? Excellent question! Allow me to now regurgitate my younger self ad naseum until we all get sick of dependent typing and, by extension, me. So I Dub This Shambolic Nightmare...
That final bullet point is the beating heart of ...uhh. Can We Get Funny Again? I Had More Fun Back in Those Days.Those days were just a few paragraphs above! And those days were useless. We didn't do anything except sit around trading diabolical puns and cutthroat jibes with keyboards. Things are better now. Our keyboards are doing something useful for once. Admittedly, that "something" is confusing even me. Let's put a concrete spin on things by reframing your above examples in terms of this bold and disturbing new from beartype import beartype
from beartype.vale import IsArgumentative # <-- *IMPORTED FOR TRUTH*
from typing import TypeAlias, TypeVar, Annotated
@beartype
class MyInterface:
length: Final[int]
@beartype
class MyImpl(MyInterface):
length = 8
T = TypeVar('T', bound=MyInterface)
@beartype
class Example(Generic[T]):
# I use an alias here for simplicity, but I would want the same in a function signature.
MyAlias: TypeAlias = Annotated[list[int], IsArgumentative[
lambda l, t: len(l) == t.length]] # <-- *OMG* the truth stuns my eyes like a UAP on fire
@beartype
def my_function(self, t: T, xs: MyAlias) -> None:
pass
Example().my_function(MyImpl(), [i for i in range(8)])Above, we see that the @beartype
class Example2:
TheMadness: TypeAlias = Annotated[list[int], IsArgumentative[
lambda l, self: len(l) == self.member]] # <-- *WOAH* more promiscuous function invasions
member: int
def __init__(self, member: int) -> None:
self.member = member
def do_something(self, list: TheMadness) -> bool:
return TrueAgain, we see that the appropriately named
|
Beta Was this translation helpful? Give feedback.
Tally-ho! Indeed, fellow @beartype hacker-master @iamrecursion has been politely begging for dependent typing for years now. Someday, @beartype hopes to make this happen for everybody. Sadly, this is not that day. I (more or less) know exactly what to do in the @beartype codebase. I just lack the time and the iron will to make this happen at the moment. Thus, I weep. 😭