Pointfree

This module provides a bunch of primitives to work with containers.

It makes composing functions with containers easier. Sometimes using methods on containers is not very helpful. Container methods are difficult to compose with other functions or methods.

Instead we can use functions that produce the same result but have the reverse semantics.

Usually, this means changing something like x.f(y) to f(x)(y).

Why would anyone need these functions when you can use methods? To create pipelines!

from returns.pipeline import pipe
from returns.result import ResultE

def returns_result(arg: int) -> ResultE[int]:
    ...

def works_with_result(arg: int) -> ResultE[int]:
    ...

def finish_work(arg: int) -> ResultE[int]:
    ...

pipe(
    returns_result,
    works_with_result,  # does not compose! Needs a container for input
    finish_work,  # does not compose either!
)

Without pointfree functions you would probably have to write:

returns_result().bind(works_with_result).bind(notifies_user)

And you need a way to somehow do this in the pipeline syntax. Remember that pipeline syntax helps make composing functions more readable and pythonic. That’s where pointfree functions become really useful.

map

map_() is a pointfree alternative to the container method .map().

It lifts a function to work from container to container. map_(f) would return f lifted to work on a container.

In other words, it modifies the function’s signature from: a -> b to: Container[a] -> Container[b]

Doing this lets us compose regular functions and containers.

>>> from returns.pointfree import map_
>>> from returns.maybe import Maybe, Some

>>> def as_int(arg: str) -> int:
...     return ord(arg)

>>> container: Maybe[str] = Some('a')
>>> # We now have two ways to compose container and as_int
>>> # 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)

This means we can compose functions in a pipeline.

>>> from returns.pointfree import map_
>>> from returns.pipeline import flow
>>> from returns.maybe import Maybe, Some, Nothing

>>> def index_of_7(arg: str) -> Maybe[int]:
...     if '7' in arg:
...         return Some(arg.index('7'))
...     return Nothing

>>> def double(num: int) -> int:
...     return num * 2

>>> assert flow(
...     '007',
...     index_of_7,    # Some(2)
...     map_(double),  # Some(4)
... ) == Some(4)

>>> # Still passes along Nothing
>>> assert flow(
...     '006',
...     index_of_7,    # Nothing
...     map_(double),  # Nothing
... ) == Nothing

bind

Pointfree bind() is an alternative to the container method .bind().

It binds a function that returns a container so that is accepts the same container type as input.

In other words, it modifies the function’s signature from: a -> Container[b] to: Container[a] -> Container[b]

Without bind() it would be very hard to declaratively compose two entities:

  1. Existing containers

  2. Existing functions that accept a regular value and return a container

We can compose these entities with .bind() when calling it on a container, but how can we do it independently?

>>> from returns.pointfree import bind
>>> from returns.maybe import Maybe, Some

>>> def index_of_1(arg: str) -> Maybe[int]:
...     if '1' in arg:
...         return Some(arg.index('1'))
...     return Nothing

>>> container = Some('A1 Steak Sauce')
>>> # We now have two way of composing these entities.
>>> # 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)
>>> # This produces the same result, but in a different order

That’s it!

We also have a long list of other bind_* functions, like:

  • bind_io to bind functions returning IO container

  • bind_result to bind functions returning Result container

  • bind_ioresult to bind functions returning IOResult container

  • bind_future to bind functions returning Future container

  • bind_async_future to bind async functions returning Future container

  • bind_future_result to bind functions returning FutureResult container

  • bind_async_future_result to bind async functions returning FutureResult container

  • bind_context to bind functions returning RequiresContext container

  • bind_context_result to bind functions returning RequiresContextResult container

  • bind_context_ioresult to bind functions returning RequiresContextIOResult container

  • bind_async to bind async functions returning Future or FutureResult

  • bind_awaitable to bind async non-container functions

alt

Pointfree alt() is an alternative to the container method .alt().

It lifts a function to act on the error contents of a container.

In other words, it modifies the function’s signature from: a -> b to: Container[_, a] -> Container[_, b]

You can think of it like map, but for the second type of a container.

>>> from returns.io import IOFailure, IOSuccess
>>> from returns.pointfree import alt

>>> 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)

>>> # When acting on a failed state, the result changes
>>> assert 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)

This inverse syntax lets us easily compose functions in a pipeline

>>> from returns.io import IOFailure, IOSuccess, IOResult
>>> from returns.pointfree import alt

>>> def always_errors(user_input: str) -> IOResult:
...     return IOFailure(len(user_input))

>>> def twice_as_bad(exit_code: int) -> int:
...     return exit_code * 2

>>> def make_error_message(exit_code: int) -> str:
...     return f'Badness level: {exit_code}'

>>> assert flow(
...     '12345',
...     always_errors,
...     alt(twice_as_bad),
...     alt(make_error_message)
... ) == IOFailure('Badness level: 10')

lash

Pointfree lash() function is an alternative to .lash() container method.

It allows better composition by lifting a function that returns a container to act on the failed state of a container.

You can think of it like bind, but for the second type of a container.

>>> from returns.pointfree import lash
>>> from returns.result import Success, Failure, Result

>>> def always_succeeds(arg: str) -> Result[int, str]:
...     return Success(1)

>>> failed: Result[int, str] = Failure('a')
>>> # We now have two way of composing these entities.
>>> # 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)

apply

Pointfree apply function allows to use .apply() container method like a function:

>>> from returns.pointfree import apply
>>> 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

If you wish to use apply inside a pipeline here’s how it might look:

>>> from returns.pointfree import apply
>>> from returns.pipeline import flow
>>> from returns.maybe import Some, Nothing, Maybe
>>> from typing import Callable

>>> def wow(arg: int) -> str:
...     return chr(arg) + '!'

>>> def my_response(is_excited: bool) -> Maybe[Callable[[int], str]]:
...     if is_excited:
...         return Some(wow)
...     return Nothing

>>> assert flow(
...     Some(97),
...     apply(my_response(True)),
... ) == Some('a!')

>>> assert flow(
...     Nothing,
...     apply(my_response(False)),
... ) == Nothing

Or with a function as the first parameter:

>>> from returns.pipeline import flow
>>> from returns.curry import curry
>>> from returns.maybe import Some

>>> @curry
... def add_curried(first: int, second: int) -> int:
...     return first + second

>>> assert flow(
...     Some(add_curried),
...     Some(2).apply,
...     Some(3).apply,
... ) == Some(5)

compose_result

Sometimes we need to manipulate the inner Result of some containers like IOResult or FutureResult. With compose_result we can do this kind of manipulation.

>>> from returns.pointfree import compose_result
>>> 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)

cond

Sometimes we need to create SingleFailableN or DiverseFailableN containers (e.g. Maybe, ResultLikeN) based on a boolean expression, cond can help us.

Consider cond to be a functional if.

See the example below:

>>> from returns.pipeline import flow
>>> from returns.pointfree import cond
>>> 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')
... ) == Success('success')

>>> assert flow(
...     returns_boolean(0),
...     cond(Result, 'success', 'failure')
... ) == Failure('failure')

Example using cond with the Maybe container:

>>> from returns.pipeline import flow
>>> from returns.pointfree import cond
>>> from returns.maybe import Maybe, Some, Nothing

>>> assert flow(
...     returns_boolean(1),
...     cond(Maybe, 'success')
... ) == Some('success')

>>> assert flow(
...     returns_boolean(0),
...     cond(Maybe, 'success')
... ) == Nothing

Further reading

API Reference

map_(function)[source]

Lifts function to be wrapped in a container for better composition.

In other words, it modifies the function’s signature from: a -> b to: Container[a] -> Container[b]

This is how it should be used:

>>> from returns.io import IO
>>> from returns.pointfree import map_

>>> def example(argument: int) -> float:
...     return argument / 2

>>> assert map_(example)(IO(1)) == IO(0.5)

Note, that this function works for all containers with .map method. See returns.primitives.interfaces.mappable.MappableN for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], TypeVar(_UpdatedType)]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_MappableKind, bound= MappableN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_MappableKind, bound= MappableN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind(function)[source]

Turns function’s input parameter from a regular value to a container.

In other words, it modifies the function signature from: a -> Container[b] to: Container[a] -> Container[b]

Similar to returns.pointfree.lash(), but works for successful containers. This is how it should be used:

>>> from returns.pointfree import bind
>>> from returns.maybe import Maybe, Some, Nothing

>>> def example(argument: int) -> Maybe[int]:
...     return Some(argument + 1)

>>> assert bind(example)(Some(1)) == Some(2)
>>> assert bind(example)(Nothing) == Nothing

Note, that this function works for all containers with .bind method. See returns.primitives.interfaces.bindable.BindableN for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], KindN[TypeVar(_BindableKind, bound= BindableN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_BindableKind, bound= BindableN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_BindableKind, bound= BindableN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_result(function)[source]

Composes successful container with a function that returns a container.

In other words, it modifies the function’s signature from: a -> Result[b, c] to: Container[a, c] -> Container[b, c]

>>> from returns.io import IOSuccess
>>> from returns.context import RequiresContextResult
>>> from returns.result import Result, Success
>>> from returns.pointfree import bind_result

>>> def returns_result(arg: int) -> Result[int, str]:
...     return Success(arg + 1)

>>> bound = bind_result(returns_result)
>>> assert bound(IOSuccess(1)) == IOSuccess(2)
>>> assert bound(RequiresContextResult.from_value(1))(...) == Success(2)
Parameters:

function (Callable[[TypeVar(_FirstType)], Result[TypeVar(_UpdatedType), TypeVar(_SecondType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_ResultLikeKind, bound= ResultLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_ResultLikeKind, bound= ResultLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_io(function)[source]

Composes successful container with a function that returns a container.

In other words, it modifies the function’s signature from: a -> IO[b] to: Container[a, c] -> Container[b, c]

>>> from returns.io import IOSuccess, IOFailure
>>> from returns.io import IO
>>> from returns.pointfree import bind_io

>>> def returns_io(arg: int) -> IO[int]:
...     return IO(arg + 1)

>>> bound = bind_io(returns_io)
>>> assert bound(IO(1)) == IO(2)
>>> assert bound(IOSuccess(1)) == IOSuccess(2)
>>> assert bound(IOFailure(1)) == IOFailure(1)
Parameters:

function (Callable[[TypeVar(_FirstType, contravariant=True)], IO[TypeVar(_UpdatedType, covariant=True)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_IOLikeKind, bound= IOLikeN), TypeVar(_FirstType, contravariant=True), TypeVar(_SecondType), TypeVar(_ThirdType, contravariant=True)]], KindN[TypeVar(_IOLikeKind, bound= IOLikeN), TypeVar(_UpdatedType, covariant=True), TypeVar(_SecondType), TypeVar(_ThirdType, contravariant=True)]]]

bind_ioresult(function)[source]

Composes successful container with a function that returns a container.

In other words, it modifies the function’s signature from: a -> IOResult[b, c] to: Container[a, c] -> Container[b, c]

>>> from returns.io import IOResult, IOSuccess
>>> from returns.context import RequiresContextIOResult
>>> from returns.pointfree import bind_ioresult

>>> def returns_ioresult(arg: int) -> IOResult[int, str]:
...     return IOSuccess(arg + 1)

>>> bound = bind_ioresult(returns_ioresult)
>>> assert bound(IOSuccess(1)) == IOSuccess(2)
>>> assert bound(
...     RequiresContextIOResult.from_value(1),
... )(...) == IOSuccess(2)
Parameters:

function (Callable[[TypeVar(_FirstType)], IOResult[TypeVar(_UpdatedType), TypeVar(_SecondType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_IOResultLikeKind, bound= IOResultLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_IOResultLikeKind, bound= IOResultLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_future(function)[source]

Compose a container and sync function returning Future.

In other words, it modifies the function signature from: a -> Future[b] to: Container[a] -> Container[b]

Similar to returns.pointfree.lash(), but works for successful containers. This is how it should be used:

>>> import anyio
>>> from returns.pointfree import bind_future
>>> from returns.future import Future
>>> from returns.io import IO

>>> def example(argument: int) -> Future[int]:
...     return Future.from_value(argument + 1)

>>> assert anyio.run(
...     bind_future(example)(Future.from_value(1)).awaitable,
... ) == IO(2)

Note, that this function works for all containers with .bind_future method. See returns.primitives.interfaces.specific.future.FutureLikeN for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], Future[TypeVar(_UpdatedType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_async_future(function)[source]

Compose a container and async function returning Future.

In other words, it modifies the function signature from: a -> Awaitable[Future[b]] to: Container[a] -> Container[b]

This is how it should be used:

>>> import anyio
>>> from returns.pointfree import bind_async_future
>>> from returns.future import Future
>>> from returns.io import IO

>>> async def example(argument: int) -> Future[int]:
...     return Future.from_value(argument + 1)

>>> assert anyio.run(
...     bind_async_future(example)(Future.from_value(1)).awaitable,
... ) == IO(2)

Note, that this function works for all containers with .bind_async_future method. See returns.primitives.interfaces.specific.future.FutureLikeN for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], Awaitable[Future[TypeVar(_UpdatedType)]]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_future_result(function)[source]

Compose a container and async function returning FutureResult.

In other words, it modifies the function signature from: a -> FutureResult[b, c] to: Container[a, c] -> Container[b, c]

This is how it should be used:

>>> import anyio
>>> from returns.pointfree import bind_future_result
>>> from returns.future import FutureResult
>>> from returns.io import IOSuccess, IOFailure

>>> def example(argument: int) -> FutureResult[int, str]:
...     return FutureResult.from_value(argument + 1)

>>> assert anyio.run(
...     bind_future_result(example)(
...         FutureResult.from_value(1),
...     ).awaitable,
... ) == IOSuccess(2)

>>> assert anyio.run(
...     bind_future_result(example)(
...         FutureResult.from_failure('a'),
...     ).awaitable,
... ) == IOFailure('a')

Note, that this function works for all containers with .bind_async_future method. See FutureResultLikeN for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], FutureResult[TypeVar(_UpdatedType), TypeVar(_SecondType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_FutureResultKind, bound= FutureResultLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_FutureResultKind, bound= FutureResultLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_async_future_result(function)[source]

Compose a container and async function returning FutureResult.

In other words, it modifies the function signature from: a -> Awaitable[FutureResult[b, c]] to: Container[a, c] -> Container[b, c]

This is how it should be used:

>>> import anyio
>>> from returns.pointfree import bind_async_future_result
>>> from returns.future import FutureResult
>>> from returns.io import IOSuccess, IOFailure

>>> async def example(argument: int) -> FutureResult[int, str]:
...     return FutureResult.from_value(argument + 1)

>>> assert anyio.run(
...     bind_async_future_result(example)(
...         FutureResult.from_value(1),
...     ).awaitable,
... ) == IOSuccess(2)

>>> assert anyio.run(
...     bind_async_future_result(example)(
...         FutureResult.from_failure('a'),
...     ).awaitable,
... ) == IOFailure('a')

Note, that this function works for all containers with .bind_async_future method. See FutureResultLikeN for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], Awaitable[FutureResult[TypeVar(_UpdatedType), TypeVar(_SecondType)]]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_FutureResultKind, bound= FutureResultLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_FutureResultKind, bound= FutureResultLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_context2(function)[source]

Composes successful container with a function that returns a container.

In other words, it modifies the function’s signature from: a -> RequresContext[b, c] to: Container[a, c] -> Container[b, c]

>>> from returns.pointfree import bind_context2
>>> from returns.context import Reader

>>> def example(argument: int) -> Reader[int, int]:
...     return Reader(lambda deps: argument + deps)

>>> assert bind_context2(example)(Reader.from_value(2))(3) == 5

Note, that this function works with only Kind2 containers with .bind_context method. See returns.primitives.interfaces.specific.reader.ReaderLike2 for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], RequiresContext[TypeVar(_UpdatedType), TypeVar(_SecondType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_Reader2Kind, bound= ReaderLike2), TypeVar(_FirstType), TypeVar(_SecondType), Any]], KindN[TypeVar(_Reader2Kind, bound= ReaderLike2), TypeVar(_UpdatedType), TypeVar(_SecondType), Any]]]

bind_context3(function)[source]

Composes successful container with a function that returns a container.

In other words, it modifies the function’s signature from: a -> RequresContext[b, c] to: Container[a, c] -> Container[b, c]

>>> from returns.context import RequiresContext, RequiresContextResult
>>> from returns.result import Success, Failure
>>> from returns.pointfree import bind_context

>>> def function(arg: int) -> RequiresContext[str, int]:
...     return RequiresContext(lambda deps: len(deps) + arg)

>>> assert bind_context(function)(
...     RequiresContextResult.from_value(2),
... )('abc') == Success(5)
>>> assert bind_context(function)(
...     RequiresContextResult.from_failure(0),
... )('abc') == Failure(0)

Note, that this function works with only Kind3 containers with .bind_context method. See returns.primitives.interfaces.specific.reader.ReaderLike3 for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], RequiresContext[TypeVar(_UpdatedType), TypeVar(_ThirdType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_Reader3Kind, bound= ReaderLike3), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_Reader3Kind, bound= ReaderLike3), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_context(function)

Useful alias for bind_context3().

Parameters:

function (Callable[[TypeVar(_FirstType)], RequiresContext[TypeVar(_UpdatedType), TypeVar(_ThirdType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_Reader3Kind, bound= ReaderLike3), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_Reader3Kind, bound= ReaderLike3), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

modify_env2(function)[source]

Modifies the second type argument of a ReaderLike2.

In other words, it modifies the function’s signature from: a -> b to: Container[x, a] -> Container[x, b]

>>> from returns.pointfree import modify_env2
>>> from returns.context import RequiresContext

>>> def multiply(arg: int) -> RequiresContext[int, int]:
...     return RequiresContext(lambda deps: arg * deps)

>>> assert modify_env2(int)(multiply(3))('4') == 12

Note, that this function works with only Kind2 containers with .modify_env method. See returns.primitives.interfaces.specific.reader.ReaderLike2 for more info.

Parameters:

function (Callable[[TypeVar(_UpdatedType)], TypeVar(_SecondType)]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_Reader2Kind, bound= ReaderLike2), TypeVar(_FirstType), TypeVar(_SecondType), Any]], KindN[TypeVar(_Reader2Kind, bound= ReaderLike2), TypeVar(_FirstType), TypeVar(_UpdatedType), Any]]]

modify_env3(function)[source]

Modifies the third type argument of a ReaderLike3.

In other words, it modifies the function’s signature from: a -> b to: Container[x, a] -> Container[x, b]

>>> from returns.pointfree import modify_env
>>> from returns.context import RequiresContextResultE
>>> from returns.result import Success, safe

>>> def divide(arg: int) -> RequiresContextResultE[float, int]:
...     return RequiresContextResultE(safe(lambda deps: arg / deps))

>>> assert modify_env(int)(divide(3))('2') == Success(1.5)
>>> assert modify_env(int)(divide(3))('0').failure()

Note, that this function works with only Kind3 containers with .modify_env method. See returns.primitives.interfaces.specific.reader.ReaderLike3 for more info.

Parameters:

function (Callable[[TypeVar(_UpdatedType)], TypeVar(_ThirdType)]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_Reader3Kind, bound= ReaderLike3), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_Reader3Kind, bound= ReaderLike3), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_UpdatedType)]]]

modify_env(function)

Useful alias for modify_env3().

Parameters:

function (Callable[[TypeVar(_UpdatedType)], TypeVar(_ThirdType)]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_Reader3Kind, bound= ReaderLike3), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_Reader3Kind, bound= ReaderLike3), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_UpdatedType)]]]

bind_context_result(function)[source]

Composes successful container with a function that returns a container.

In other words, it modifies the function’s signature from: a -> ReaderResult[b, c, e] to: Container[a, c, e] -> Container[b, c, e]

>>> from returns.pointfree import bind_context_result
>>> from returns.context import ReaderIOResult, ReaderResult
>>> from returns.io import IOSuccess, IOFailure

>>> def example(argument: int) -> ReaderResult[int, str, str]:
...     return ReaderResult.from_value(argument + 1)

>>> assert bind_context_result(example)(
...     ReaderIOResult.from_value(1),
... )(...) == IOSuccess(2)
>>> assert bind_context_result(example)(
...     ReaderIOResult.from_failure('a'),
... )(...) == IOFailure('a')
Parameters:

function (Callable[[TypeVar(_FirstType)], RequiresContextResult[TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_ReaderResultLikeKind, bound= ReaderResultLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_ReaderResultLikeKind, bound= ReaderResultLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_context_ioresult(function)[source]

Lifts function from RequiresContextIOResult for better composition.

In other words, it modifies the function’s signature from: a -> RequiresContextIOResult[env, b, c] to: Container[env, a, c] -> Container[env, b, c]

>>> import anyio
>>> from returns.context import (
...     RequiresContextFutureResult,
...     RequiresContextIOResult,
... )
>>> from returns.io import IOSuccess, IOFailure
>>> from returns.pointfree import bind_context_ioresult

>>> def function(arg: int) -> RequiresContextIOResult[str, int, str]:
...     return RequiresContextIOResult(
...         lambda deps: IOSuccess(len(deps) + arg),
...     )

>>> assert anyio.run(bind_context_ioresult(function)(
...     RequiresContextFutureResult.from_value(2),
... )('abc').awaitable) == IOSuccess(5)
>>> assert anyio.run(bind_context_ioresult(function)(
...     RequiresContextFutureResult.from_failure(0),
... )('abc').awaitable) == IOFailure(0)
Parameters:

function (Callable[[TypeVar(_FirstType)], RequiresContextIOResult[TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_ReaderIOResultLikeKind, bound= ReaderIOResultLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_ReaderIOResultLikeKind, bound= ReaderIOResultLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_async(function)[source]

Compose a container and async function returning a container.

In other words, it modifies the function’s signature from: a -> Awaitable[Container[b]] to: Container[a] -> Container[b]

This is how it should be used:

>>> import anyio
>>> from returns.future import Future
>>> from returns.io import IO
>>> from returns.pointfree import bind_async

>>> async def coroutine(x: int) -> Future[str]:
...    return Future.from_value(str(x + 1))

>>> bound = bind_async(coroutine)(Future.from_value(1))
>>> assert anyio.run(bound.awaitable) == IO('2')

Note, that this function works for all containers with .bind_async method. See returns.primitives.interfaces.specific.future.FutureLikeN for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], Awaitable[KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_awaitable(function)[source]

Composes a container a regular async function.

This function should return plain, non-container value.

In other words, it modifies the function’s signature from: a -> Awaitable[b] to: Container[a] -> Container[b]

This is how it should be used:

>>> import anyio
>>> from returns.future import Future
>>> from returns.io import IO
>>> from returns.pointfree import bind_awaitable

>>> async def coroutine(x: int) -> int:
...    return x + 1

>>> assert anyio.run(
...     bind_awaitable(coroutine)(Future.from_value(1)).awaitable,
... ) == IO(2)

Note, that this function works for all containers with .bind_awaitable method. See returns.primitives.interfaces.specific.future.FutureLikeN for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], Awaitable[TypeVar(_UpdatedType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_FutureKind, bound= FutureLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

bind_optional(function)[source]

Binds a function returning optional value over a container.

In other words, it modifies the function’s signature from: a -> Optional[b] to: Container[a] -> Container[b]

>>> from typing import Optional
>>> from returns.pointfree import bind_optional
>>> from returns.maybe import Some, Nothing

>>> def example(argument: int) -> Optional[int]:
...     return argument + 1 if argument > 0 else None

>>> assert bind_optional(example)(Some(1)) == Some(2)
>>> assert bind_optional(example)(Some(0)) == Nothing
>>> assert bind_optional(example)(Nothing) == Nothing

Note, that this function works for all containers with .bind_optional method. See returns.primitives.interfaces.specific.maybe._MaybeLikeKind for more info.

Parameters:

function (Callable[[TypeVar(_FirstType)], Optional[TypeVar(_UpdatedType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_MaybeLikeKind, bound= MaybeLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_MaybeLikeKind, bound= MaybeLikeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

compose_result(function)[source]

Composes inner Result with IOResultLike returning function.

Can be useful when you need an access to both states of the result.

>>> from returns.io import IOResult, IOSuccess, IOFailure
>>> from returns.pointfree import compose_result
>>> from returns.result import Result

>>> def modify_string(container: Result[str, str]) -> IOResult[str, str]:
...     return IOResult.from_result(
...         container.map(str.upper).alt(str.lower),
...     )

>>> assert compose_result(modify_string)(
...     IOSuccess('success')
... ) == IOSuccess('SUCCESS')
>>> assert compose_result(modify_string)(
...     IOFailure('FAILURE')
... ) == IOFailure('failure')
Parameters:

function (Callable[[Result[TypeVar(_FirstType), TypeVar(_SecondType)]], KindN[TypeVar(_IOResultLikeKind, bound= IOResultLikeN), TypeVar(_NewFirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_IOResultLikeKind, bound= IOResultLikeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_IOResultLikeKind, bound= IOResultLikeN), TypeVar(_NewFirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]

cond(container_type: Type[_SingleFailableKind], success_value: _ValueType) Kinded[Callable[[bool], KindN[_SingleFailableKind, _ValueType, _ErrorType, Any]]][source]
cond(container_type: Type[_DiverseFailableKind], success_value: _ValueType, error_value: _ErrorType) Kinded[Callable[[bool], KindN[_DiverseFailableKind, _ValueType, _ErrorType, Any]]]

Reduce the boilerplate when choosing paths.

Works with SingleFailableN (e.g. Maybe) and DiverseFailableN (e.g. Result).

Example using cond with the Result container:

>>> from returns.pointfree import cond
>>> from returns.result import Failure, Result, Success

>>> assert cond(Result, 'success', 'failure')(True) == Success('success')
>>> assert cond(Result, 'success', 'failure')(False) == Failure('failure')

Example using cond with the Maybe container:

>>> from returns.maybe import Maybe, Some, Nothing

>>> assert cond(Maybe, 10.0)(True) == Some(10.0)
>>> assert cond(Maybe, 10.0)(False) == Nothing
Parameters:
  • container_type (Union[Type[TypeVar(_SingleFailableKind, bound= SingleFailableN)], Type[TypeVar(_DiverseFailableKind, bound= DiverseFailableN)]]) –

  • success_value (TypeVar(_ValueType)) –

  • error_value (Optional[TypeVar(_ErrorType)]) –

alt(function)[source]

Lifts function to be wrapped in a container for better composition.

In other words, it modifies the function’s signature from: a -> b to: Container[a] -> Container[b]

This is how it should be used:

>>> from returns.io import IOFailure, IOSuccess
>>> from returns.pointfree import alt

>>> def example(argument: int) -> float:
...     return argument / 2

>>> assert alt(example)(IOSuccess(1)) == IOSuccess(1)
>>> assert alt(example)(IOFailure(4)) == IOFailure(2.0)

Note, that this function works for all containers with .alt method. See returns.primitives.interfaces.altable.AltableN for more info.

Parameters:

function (Callable[[TypeVar(_SecondType)], TypeVar(_UpdatedType)]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_AltableKind, bound= AltableN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_AltableKind, bound= AltableN), TypeVar(_FirstType), TypeVar(_UpdatedType), TypeVar(_ThirdType)]]]

lash(function)[source]

Turns function’s input parameter from a regular value to a container.

In other words, it modifies the function signature from: a -> Container[b] to: Container[a] -> Container[b]

Similar to returns.pointfree.bind(), but works for failed containers.

This is how it should be used:

>>> from returns.pointfree import lash
>>> from returns.result import Success, Failure, Result

>>> def example(argument: int) -> Result[str, int]:
...     return Success(argument + 1)

>>> assert lash(example)(Success('a')) == Success('a')
>>> assert lash(example)(Failure(1)) == Success(2)

Note, that this function works for all containers with .lash method. See returns.interfaces.lashable.Lashable for more info.

Parameters:

function (Callable[[TypeVar(_SecondType)], KindN[TypeVar(_LashableKind, bound= LashableN), TypeVar(_FirstType), TypeVar(_UpdatedType), TypeVar(_ThirdType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_LashableKind, bound= LashableN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_LashableKind, bound= LashableN), TypeVar(_FirstType), TypeVar(_UpdatedType), TypeVar(_ThirdType)]]]

unify(function)[source]

Composes successful container with a function that returns a container.

Similar to bind() but has different type. It returns Result[ValueType, Union[OldErrorType, NewErrorType]] instead of Result[ValueType, OldErrorType].

So, it can be more useful in some situations. Probably with specific exceptions.

>>> from returns.methods import cond
>>> from returns.pointfree import unify
>>> from returns.result import Result, Success, Failure

>>> def bindable(arg: int) -> Result[int, int]:
...     return cond(Result, arg % 2 == 0, arg + 1, arg - 1)

>>> assert unify(bindable)(Success(2)) == Success(3)
>>> assert unify(bindable)(Success(1)) == Failure(0)
>>> assert unify(bindable)(Failure(42)) == Failure(42)
Parameters:

function (Callable[[TypeVar(_FirstType)], KindN[TypeVar(_DiverseFailableKind, bound= DiverseFailableN), TypeVar(_NewFirstType), TypeVar(_NewSecondType), TypeVar(_NewThirdType)]]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_DiverseFailableKind, bound= DiverseFailableN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_DiverseFailableKind, bound= DiverseFailableN), TypeVar(_NewFirstType), Union[TypeVar(_SecondType), TypeVar(_NewSecondType)], TypeVar(_NewThirdType)]]]

apply(container)[source]

Turns container containing a function into a callable.

In other words, it modifies the function signature from: Container[a -> b] to: Container[a] -> Container[b]

This is how it should be used:

>>> from returns.pointfree import apply
>>> from returns.maybe import Some, Nothing

>>> def example(argument: int) -> int:
...     return argument + 1

>>> assert apply(Some(example))(Some(1)) == Some(2)
>>> assert apply(Some(example))(Nothing) == Nothing
>>> assert apply(Nothing)(Some(1)) == Nothing
>>> assert apply(Nothing)(Nothing) == Nothing

Note, that this function works for all containers with .apply method. See returns.interfaces.applicative.ApplicativeN for more info.

Parameters:

container (KindN[TypeVar(_ApplicativeKind, bound= ApplicativeN), Callable[[TypeVar(_FirstType)], TypeVar(_UpdatedType)], TypeVar(_SecondType), TypeVar(_ThirdType)]) –

Return type:

Kinded[Callable[[KindN[TypeVar(_ApplicativeKind, bound= ApplicativeN), TypeVar(_FirstType), TypeVar(_SecondType), TypeVar(_ThirdType)]], KindN[TypeVar(_ApplicativeKind, bound= ApplicativeN), TypeVar(_UpdatedType), TypeVar(_SecondType), TypeVar(_ThirdType)]]]