dbrattli / Expression

Pragmatic functional programming for Python inspired by F#
https://expression.readthedocs.io
MIT License
421 stars 30 forks source link

Add `NonEmptyBlock` class and utility functions #178

Open brendanmaguire opened 7 months ago

brendanmaguire commented 7 months ago

Closes #177

brendanmaguire commented 7 months ago

~This is still a WIP. I have tests running locally but need to fix them up and push.~ Edit: Done

@dbrattli , interested to hear your thoughts. Would this be a collection type you'd be willing to merge?

dbrattli commented 7 months ago

Looks very nice. Could we perhaps subclass Block to avoid so much code duplication? E.g by using the new Self type in block.py so functions return NonEmptyBlock instead of Block?

brendanmaguire commented 7 months ago

Looks very nice. Could we perhaps subclass Block to avoid so much code duplication? E.g by using the new Self type in block.py so functions return NonEmptyBlock instead of Block?

Thanks for taking a look 👍

Some methods were not implemented in NonEmptyBlock as they wouldn't make sense. And some new ones were implemented. This change might involve pulling out the common part to an abstract BaseBlock class.

It might be a while before I get back to this PR again but I will take a look into that and see what's possible at some point.

brendanmaguire commented 6 months ago

Hey @dbrattli . I just got around to looking at refactoring this to make NonEmptyBlock a subtype of Block. It seems it won't work because Self cannot be parameterized.

For example, if I change Block#collects signature to:

    def collect(self, mapping: Callable[[_TSource], Block[_TResult]]) -> Self[_TResult]:

I get the following error from pyright:

Expected no type arguments for class "Self"