Skip to content

Constrain relocating functors to require move-constructible value/error #250

Description

@Bronek

Problem

A functor that returns a fresh monad by value must relocate whatever it carries through, so the carried side must be move-constructible. The invocable_* concepts don't require this, so an immovable value/error type satisfies the concept and then hard-errors deep in the body (e.g. an or_else substitution failure) instead of cleanly SFINAE-rejecting.

Surfaced while adding value_or tests: fn::expected<Immovable, E> | value_or(args...) reports as invocable, then fails to compile.

Affected functors (verbs)

Functor Relocates Needs movable
value_or existing value (success branch) value
recover existing value (success branch) value
fail existing error (error branch) error
filter whole monad via return FWD(v) value + error

and_then / transform / or_else / transform_error delegate to the expected member and likely reject transitively (to confirm). inspect / inspect_error return V&& (no relocation) and discard returns void — none needed.

Proposal

Add an explicit movability requirement to the relevant invocable_* concepts so immovable types are SFINAE-rejected, plus negative invocability tests documenting the boundary.

Open question: simple std::is_move_constructible_v<T> vs. a value-category-precise std::is_constructible_v<T, decltype(carried)>.

Assisted-by: Claude:claude-opus-4-8

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrelease-0.1Planned for release 0.1

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions