Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flow / pipe from list of callables #444

Closed
gjedlicska opened this issue Jun 29, 2020 · 2 comments
Closed

Flow / pipe from list of callables #444

gjedlicska opened this issue Jun 29, 2020 · 2 comments
Labels
question Further information is requested

Comments

@gjedlicska
Copy link

gjedlicska commented Jun 29, 2020

I'm working on a validator pipeline, like the example above:

from dataclasses import dataclass
from returns.result import Success, Failure, ResultE
from typing import List, Callable
from returns.pipeline import flow
from returns.pointfree import bind


@dataclass
class ValidatorPipeline:
    validators: List[Callable[[str], ResultE[str]]]

    def __call__(self, data: str) -> ResultE[str]:
        return flow(
            Success(data), *(bind(validator) for validator in self.validators),
        ) # type: ignore


if __name__ == "__main__":
    validator = ValidatorPipeline(
        [
            lambda a: Success(a) if len(a) > 3 else Failure(ValueError("too short")),
            lambda a: Success(a) if len(a) < 10 else Failure(ValueError("too long")),
            lambda a: Success(a) if "this" in a else Failure(ValueError("not this")),
        ]
    )

    print(validator("asdf").failure())
    print(validator("this and that").failure())
    print(validator("just this").unwrap())

I know that pipe and i guess flow has a limitation on the number of functions it is capable of composing together, while still being able to do type checking. But given the code above is this a valid approach? I know that some checks have to be in place, for this to work, like atleast one validator function is required, but I like how clean the pipeline looks.

@sobolevn
Copy link
Member

sobolevn commented Jun 29, 2020

Hi @gjedlicska!

I know that pipe and i guess flow has a limitation on the number of functions it is capable of composing together, while still being able to do type checking

They used to have this restriction in <0.14, but now they are capable of working with any number of functions.

But given the code above is this a valid approach?

It is, but you will lost your typing in *(bind(validator) for validator in self.validators)
Because, * cannot reveal the inner Tuple[...] type. This is a mypy specific issue.
I am pretty sure that we also don't handle tuple unpacking in our custom plugin. Because there's no need in this before mypy will reveal types correctly.

All in all, you can use this code. It should work, with some Any here and there.

Related #258

@sobolevn sobolevn added the question Further information is requested label Jun 29, 2020
@gjedlicska
Copy link
Author

gjedlicska commented Jun 29, 2020

Hey @sobolevn

Thanks for the quick answer 👏️, I thought aswell, that the shortcommings are rooted in mypy. Externally the typing looks valid, with the type hinting of the __call__ method, only the local ignore is required to make mypy happy.

Its also good to know, that the pipe length limitations have been lifted.
Thanks for your response.
I'm closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Development

No branches or pull requests

2 participants