Skip to content

Commit

Permalink
fix: remove callable if_left and if_right
Browse files Browse the repository at this point in the history
  • Loading branch information
edeckers committed Jan 9, 2025
1 parent 4152832 commit 7307e30
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 76 deletions.
34 changes: 8 additions & 26 deletions src/pyella/either.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ def fmap(self, apply: Callable[[TB_co], TC_co]) -> Either[TA_co, TC_co]:

def if_left(
self,
fallback_value_or_fn: TB_co | Callable[[TA_co], TB_co], # type: ignore [misc] # covariant arg ok, b/c function is pure
fallback: TB_co, # type: ignore [misc] # covariant arg ok, b/c function is pure
) -> TB_co:
"""
Alias for :py:func:`if_left(self, fallback) <if_left>`
"""
return if_left(self, fallback_value_or_fn)
return if_left(self, fallback)

def if_left_fn(
self,
Expand All @@ -89,12 +89,12 @@ def if_left_fn(

def if_right(
self,
fallback_value_or_fn: TA_co | Callable[[TB_co], TA_co], # type: ignore [misc] # covariant arg ok, b/c function is pure
fallback: TA_co, # type: ignore [misc] # covariant arg ok, b/c function is pure
) -> TA_co:
"""
Alias for :py:func:`if_right(self, fallback) <if_right>`
"""
return if_right(self, fallback_value_or_fn)
return if_right(self, fallback)

def if_right_fn(
self,
Expand Down Expand Up @@ -294,23 +294,14 @@ def right_type_helper(value: TB_co) -> Either[TC_co, TB_co]: # type: ignore [mi

def if_left(
em0: Either[TA_co, TB_co],
fallback_value_or_fn: TB_co | Callable[[TA_co], TB_co], # type: ignore [misc] # covariant arg ok, b/c function is pure
fallback: TB_co, # type: ignore [misc] # covariant arg ok, b/c function is pure
) -> TB_co:
"""
Return the contents of a :py:class:`Right[TB] <Right>` or a fallback value if it's :py:class:`Left`
.. note:: Haskell: `fromRight <https://hackage.haskell.org/package/base/docs/Data-Either.html#v:fromRight>`_
"""
if not callable(fallback_value_or_fn):
return fallback_value_or_fn if em0.is_left() else cast(TB_co, em0.value)

return if_left_fn(
em0,
cast(
Callable[[TA_co], TB_co],
fallback_value_or_fn,
),
)
return fallback if em0.is_left() else cast(TB_co, em0.value)


def if_left_fn(
Expand All @@ -327,23 +318,14 @@ def if_left_fn(

def if_right(
em0: Either[TA_co, TB_co],
fallback_value_or_fn: TA_co | Callable[[TB_co], TA_co], # type: ignore [misc] # covariant arg ok, b/c function is pure
fallback: TA_co, # type: ignore [misc] # covariant arg ok, b/c function is pure
) -> TA_co:
"""
Return the contents of a :py:class:`Left` or a fallback value if it's :py:class:`Right`
.. note:: Haskell: `fromLeft <https://hackage.haskell.org/package/base/docs/Data-Either.html#v:fromLeft>`_
"""
if not callable(fallback_value_or_fn):
return fallback_value_or_fn if em0.is_right() else cast(TA_co, em0.value)

return if_right_fn(
em0,
cast(
Callable[[TB_co], TA_co],
fallback_value_or_fn,
),
)
return fallback if em0.is_right() else cast(TA_co, em0.value)


def if_right_fn(
Expand Down
58 changes: 8 additions & 50 deletions src/tests/test_either.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ def test_if_left_returns_expected_results(self):
# arrange
some_value = random_str()
some_fallback_value = random_str()
some_fallback_fn = lambda v: str(v) + "!"

some_left_value = random_int()

Expand All @@ -289,58 +288,35 @@ def test_if_left_returns_expected_results(self):

# act
right_result_from_value = some_right.if_left(some_fallback_value)
right_result_from_fn = some_right.if_left(some_fallback_fn)
left_result_from_value = some_left.if_left(some_fallback_value)
left_result_from_fn = some_left.if_left(some_fallback_fn)

# assert
self.assertIsInstance(
right_result_from_value,
str,
"Calling `if_left` with fallback value on Right should return unaltered Right value",
)
self.assertIsInstance(
right_result_from_fn,
str,
"Calling `if_left` with Callable on Left should return unaltered Right value",
)
self.assertIsInstance(
left_result_from_value,
str,
"Calling `if_left` with fallback value on Left should return fallback value",
)
self.assertIsInstance(
left_result_from_fn,
str,
"Calling `if_left` with Callable on Left should return fallback value",
)

self.assertEqual(
some_value,
right_result_from_value,
"Calling `if_left` on Right should return unaltered Right value",
)
self.assertEqual(
some_value,
right_result_from_fn,
"Calling `if_left` on Right with Callable should return unaltered Right value",
)
self.assertEqual(
some_fallback_value,
left_result_from_value,
"Calling `if_left` on Left should return unalterted fallback value",
)
self.assertEqual(
some_fallback_fn(some_left_value),
left_result_from_fn,
"Calling `if_left` on Left with Callable should return mapped Left value",
)

def test_if_right_returns_expected_results(self):
# arrange
some_value = random_int()
some_value = random_str()
some_fallback_value = random_int()
some_fallback_fn = lambda v: v * 2

some_left_value = random_int()

Expand All @@ -349,57 +325,37 @@ def test_if_right_returns_expected_results(self):

# act
right_result_from_value = some_right.if_right(some_fallback_value)
right_result_from_fn = some_right.if_right(some_fallback_fn)
left_result_from_value = some_left.if_right(some_fallback_value)
left_result_from_fn = some_left.if_right(some_fallback_fn)

# assert
self.assertIsInstance(
right_result_from_value,
int,
"Calling `if_right` with fallback value on Right should return unaltered Right value",
)
self.assertIsInstance(
right_result_from_fn,
int,
"Calling `if_right` with Callable on Left should return unaltered Right value",
)
self.assertIsInstance(
left_result_from_value,
int,
"Calling `if_right` with fallback value on Left should return fallback value",
)
self.assertIsInstance(
left_result_from_fn,
int,
"Calling `if_right` with Callable on Left should return fallback value",
)

self.assertEqual(
some_fallback_value,
right_result_from_value,
"Calling `if_right` on Right should return unalterted fallback value",
)
self.assertEqual(
some_fallback_fn(some_value),
right_result_from_fn,
"Calling `if_right` on Right with Callable should return mapped Left value",
)
self.assertEqual(
some_left_value,
left_result_from_value,
"Calling `if_right` on Left should return unaltered Left value",
)
self.assertEqual(
some_left_value,
left_result_from_fn,
"Calling `if_right` on Left with Callable should return unaltered Left value",
)

def test_if_left_fn_returns_expected_results(self):
# arrange
some_value = random_str()
some_fallback_fn = lambda v: str(v) + "!"

def some_fallback_fn(v: int) -> str:
return str(v) + "!"

some_left_value = random_int()

Expand Down Expand Up @@ -435,8 +391,10 @@ def test_if_left_fn_returns_expected_results(self):

def test_if_right_fn_returns_expected_results(self):
# arrange
some_value = random_int()
some_fallback_fn = lambda v: v * 2
some_value = random_str()

def some_fallback_fn(v: str) -> int:
return len(v)

some_left_value = random_int()

Expand Down

0 comments on commit 7307e30

Please sign in to comment.