Skip to content

Async function composition #738

Closed
Closed
@evhub

Description

@evhub

There should be a way to write point-free async functions. What we need is some implementation of fmap and bind/join, treating either an awaitable itself or an async function returning an awaitable as the underlying monad. For example:

def and_then[**T, U, V](
	async_func: async (**T) -> U,
    normal_func: U -> V,
) -> async (**T) -> V =
    """Monadic fmap for async functions."""
    async def (*args, **kwargs) -> normal_func(await async_func(*args, **kwargs))

def then_await[**T, U](
    async_async_func: async (**T) -> Awaitable[U],
) -> async (**T) -> U =
    """Monadic join for async functions."""
    async def (*args, **kwargs) -> await (await async_async_func(*args, **kwargs))

def and_then_await[**T, U, V](
	async_f: async (**T) -> U,
    async_g: async U -> V,
) -> async (**T) -> V =
    """Monadic bind for async functions."""
    async_f `and_then` async_g `then_await`

which would let you do stuff like

my_async_func: async int -> int
new_async_func: async str -> int = (
    int
    ..> my_async_func
    `and_then`
    (.*2)
    `and_then_await`
    my_async_func
)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions