Skip to content

Commit

Permalink
Issue 1693 - Documentation concerning ´cond´ functions (#1712)
Browse files Browse the repository at this point in the history
* 📝 encourage import of methods and pointfree modules

* 📝 encourage import of pointfree module

* 📝 notes pointing out name clash

* 🔥 removed `pointfree.` from commented
  • Loading branch information
Dynge committed Oct 24, 2023
1 parent 7f025d8 commit 8eb62a1
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 44 deletions.
22 changes: 13 additions & 9 deletions docs/pages/methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ The following useful methods can be used to interact with interfaces.
cond
----

.. note::
``cond`` is also the name of a function in the :ref:`pointfree` module.
Therefore we encourage to import the modules ``pointfree`` and ``methods``
directly instead of their functions.

Reduce the boilerplate when choosing paths with ``DiverseFailableN``.
Think of this method as a functional ``if`` alternative
for successful or failed types.
Expand All @@ -27,11 +32,11 @@ Can be replaced with this:

.. code:: python
>>> from returns.methods import cond
>>> from returns import methods
>>> from returns.result import Failure, Result, Success
>>> def is_numeric(string: str) -> Result[str, str]:
... return cond(
... return methods.cond(
... Result,
... string.isnumeric(),
... 'It is a number',
Expand All @@ -53,10 +58,10 @@ Unwraps either a successful or failed value.
.. code:: python
>>> from returns.io import IO, IOSuccess, IOFailure
>>> from returns.methods import unwrap_or_failure
>>> from returns import methods
>>> assert unwrap_or_failure(IOSuccess(1)) == IO(1)
>>> assert unwrap_or_failure(IOFailure('a')) == IO('a')
>>> assert methods.unwrap_or_failure(IOSuccess(1)) == IO(1)
>>> assert methods.unwrap_or_failure(IOFailure('a')) == IO('a')
Useful when you have a ``ResultLike`` value with correctly handled error value,
for example with :func:`~returns.pointfree.bimap.bimap`.
Expand All @@ -65,12 +70,11 @@ Here's a full example:
.. code:: python
>>> from returns.result import Failure, Result, Success
>>> from returns.methods import unwrap_or_failure
>>> from returns.pointfree import bimap
>>> from returns import methods, pointfree
>>> instance: Result[int, str] = Success(1)
>>> error_handled = bimap(lambda inr: inr + 1, lambda _: 0)(instance)
>>> assert isinstance(unwrap_or_failure(error_handled), int)
>>> error_handled = pointfree.bimap(lambda inr: inr + 1, lambda _: 0)(instance)
>>> assert isinstance(methods.unwrap_or_failure(error_handled), int)
API Reference
Expand Down
75 changes: 40 additions & 35 deletions docs/pages/pointfree.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Doing this lets us compose regular functions and containers.

.. code:: python
>>> from returns.pointfree import map_
>>> from returns import pointfree
>>> from returns.maybe import Maybe, Some
>>> def as_int(arg: str) -> int:
Expand All @@ -78,13 +78,13 @@ Doing this lets us compose regular functions and containers.
>>> # 1. Via ``.map()``:
>>> assert container.map(as_int) == Some(97)
>>> # 2. Or via ``map_()``, like above but in the reverse order:
>>> assert map_(as_int)(container) == Some(97)
>>> assert pointfree.map_(as_int)(container) == Some(97)
This means we can compose functions in a pipeline.

.. code:: python
>>> from returns.pointfree import map_
>>> from returns import pointfree
>>> from returns.pipeline import flow
>>> from returns.maybe import Maybe, Some, Nothing
Expand All @@ -98,15 +98,15 @@ This means we can compose functions in a pipeline.
>>> assert flow(
... '007',
... index_of_7, # Some(2)
... map_(double), # Some(4)
... index_of_7, # Some(2)
... pointfree.map_(double), # Some(4)
... ) == Some(4)
>>> # Still passes along Nothing
>>> assert flow(
... '006',
... index_of_7, # Nothing
... map_(double), # Nothing
... index_of_7, # Nothing
... pointfree.map_(double), # Nothing
... ) == Nothing
bind
Expand All @@ -132,7 +132,7 @@ but how can we do it independently?

.. code:: python
>>> from returns.pointfree import bind
>>> from returns import pointfree
>>> from returns.maybe import Maybe, Some
>>> def index_of_1(arg: str) -> Maybe[int]:
Expand All @@ -145,7 +145,7 @@ but how can we do it independently?
>>> # 1. Via ``.bind``:
>>> assert container.bind(index_of_1) == Some(1)
>>> # 2. Or via the ``bind`` function.
>>> assert bind(index_of_1)(container) == Some(1)
>>> assert pointfree.bind(index_of_1)(container) == Some(1)
>>> # This produces the same result, but in a different order
That's it!
Expand Down Expand Up @@ -187,26 +187,26 @@ You can think of it like ``map``, but for the second type of a container.
.. code:: python
>>> from returns.io import IOFailure, IOSuccess
>>> from returns.pointfree import alt
>>> from returns import pointfree
>>> def half_as_bad(error_code: int) -> float:
... return error_code / 2
>>> # When acting on a successful state, nothing happens.
>>> assert alt(half_as_bad)(IOSuccess(1)) == IOSuccess(1)
>>> assert pointfree.alt(half_as_bad)(IOSuccess(1)) == IOSuccess(1)
>>> # When acting on a failed state, the result changes
>>> assert alt(half_as_bad)(IOFailure(4)) == IOFailure(2.0)
>>> assert pointfree.alt(half_as_bad)(IOFailure(4)) == IOFailure(2.0)
>>> # This is equivalent to IOFailure(4).alt(half_as_bad)
>>> assert alt(half_as_bad)(IOFailure(4)) == IOFailure(4).alt(half_as_bad)
>>> assert pointfree.alt(half_as_bad)(IOFailure(4)) == IOFailure(4).alt(half_as_bad)
This inverse syntax lets us easily compose functions in a pipeline

.. code:: python
>>> from returns.io import IOFailure, IOSuccess, IOResult
>>> from returns.pointfree import alt
>>> from returns import pointfree
>>> def always_errors(user_input: str) -> IOResult:
... return IOFailure(len(user_input))
Expand All @@ -220,8 +220,8 @@ This inverse syntax lets us easily compose functions in a pipeline
>>> assert flow(
... '12345',
... always_errors,
... alt(twice_as_bad),
... alt(make_error_message)
... pointfree.alt(twice_as_bad),
... pointfree.alt(make_error_message)
... ) == IOFailure('Badness level: 10')
Expand All @@ -238,7 +238,7 @@ You can think of it like ``bind``, but for the second type of a container.

.. code:: python
>>> from returns.pointfree import lash
>>> from returns import pointfree
>>> from returns.result import Success, Failure, Result
>>> def always_succeeds(arg: str) -> Result[int, str]:
Expand All @@ -249,7 +249,7 @@ You can think of it like ``bind``, but for the second type of a container.
>>> # 1. Via ``.lash``:
>>> assert failed.lash(always_succeeds) == Success(1)
>>> # 2. Or via ``lash`` function, the same but in the inverse way:
>>> assert lash(always_succeeds)(failed) == Success(1)
>>> assert pointfree.lash(always_succeeds)(failed) == Success(1)
apply
Expand All @@ -260,23 +260,23 @@ to use ``.apply()`` container method like a function:

.. code:: python
>>> from returns.pointfree import apply
>>> from returns import pointfree
>>> from returns.maybe import Some, Nothing
>>> def wow(arg: int) -> str:
... return chr(arg) + '!'
>>> assert apply(Some(wow))(Some(97)) == Some('a!')
>>> assert apply(Some(wow))(Some(98)) == Some('b!')
>>> assert apply(Some(wow))(Nothing) == Nothing
>>> assert apply(Nothing)(Nothing) == Nothing
>>> assert pointfree.apply(Some(wow))(Some(97)) == Some('a!')
>>> assert pointfree.apply(Some(wow))(Some(98)) == Some('b!')
>>> assert pointfree.apply(Some(wow))(Nothing) == Nothing
>>> assert pointfree.apply(Nothing)(Nothing) == Nothing
If you wish to use ``apply`` inside a pipeline
here's how it might look:

.. code:: python
>>> from returns.pointfree import apply
>>> from returns import pointfree
>>> from returns.pipeline import flow
>>> from returns.maybe import Some, Nothing, Maybe
>>> from typing import Callable
Expand All @@ -291,12 +291,12 @@ here's how it might look:
>>> assert flow(
... Some(97),
... apply(my_response(True)),
... pointfree.apply(my_response(True)),
... ) == Some('a!')
>>> assert flow(
... Nothing,
... apply(my_response(False)),
... pointfree.apply(my_response(False)),
... ) == Nothing
Or with a function as the first parameter:
Expand Down Expand Up @@ -326,19 +326,24 @@ kind of manipulation.

.. code:: python
>>> from returns.pointfree import compose_result
>>> from returns import pointfree
>>> from returns.io import IOResult, IOSuccess, IOFailure
>>> from returns.result import Result
>>> def cast_to_str(container: Result[float, int]) -> IOResult[str, int]:
... return IOResult.from_result(container.map(str))
>>> assert compose_result(cast_to_str)(IOSuccess(42.0)) == IOSuccess('42.0')
>>> assert compose_result(cast_to_str)(IOFailure(1)) == IOFailure(1)
>>> assert pointfree.compose_result(cast_to_str)(IOSuccess(42.0)) == IOSuccess('42.0')
>>> assert pointfree.compose_result(cast_to_str)(IOFailure(1)) == IOFailure(1)
cond
----

.. note::
``cond`` is also the name of a function in the :ref:`methods` module.
Therefore we encourage to import the modules ``pointfree`` and ``methods``
directly instead of their functions.

Sometimes we need to create ``SingleFailableN`` or ``DiverseFailableN``
containers (e.g. ``Maybe``, ``ResultLikeN``) based on a boolean expression,
``cond`` can help us.
Expand All @@ -350,38 +355,38 @@ See the example below:
.. code:: python
>>> from returns.pipeline import flow
>>> from returns.pointfree import cond
>>> from returns import pointfree
>>> from returns.result import Result, Failure, Success
>>> def returns_boolean(arg: int) -> bool:
... return bool(arg)
>>> assert flow(
... returns_boolean(1),
... cond(Result, 'success', 'failure')
... pointfree.cond(Result, 'success', 'failure')
... ) == Success('success')
>>> assert flow(
... returns_boolean(0),
... cond(Result, 'success', 'failure')
... pointfree.cond(Result, 'success', 'failure')
... ) == Failure('failure')
Example using ``cond`` with the ``Maybe`` container:

.. code:: python
>>> from returns.pipeline import flow
>>> from returns.pointfree import cond
>>> from returns import pointfree
>>> from returns.maybe import Maybe, Some, Nothing
>>> assert flow(
... returns_boolean(1),
... cond(Maybe, 'success')
... pointfree.cond(Maybe, 'success')
... ) == Some('success')
>>> assert flow(
... returns_boolean(0),
... cond(Maybe, 'success')
... pointfree.cond(Maybe, 'success')
... ) == Nothing
Expand Down

0 comments on commit 8eb62a1

Please sign in to comment.