Package groovy.transform

# Annotation Interface Monadic

@Documented @Incubating @Target(TYPE) @Retention(RUNTIME) public @interface Monadic
Marks a type as participating in monadic comprehensions (the `DO` macro). Optional members declare the bind/map method names when they diverge from the structural convention (`flatMap`/`map`). When both are omitted, the annotation merely opts the type in and the structural defaults apply.

Modelled on `Reducer`: a pure marker, read by tooling, with no AST transformation. The runtime dispatcher and the type checker match this annotation by simple name (`Monadic`), exactly as `groovy.typecheckers.CombinerChecker` matches `@Reducer`/`@Associative`.

Lawful carriers and value equality. A comprehension composes monadic values, which are only meaningful up to value equality: two carriers wrapping equal contents denote the same result. A data-style carrier should therefore provide structural `equals`/`hashCode` (Groovy's `==` dispatches to `equals`); without them, results compare by identity and the laws — right identity and functor identity in particular — are reference-unequal and silently fail to hold. This does not apply to effectful or lazy carriers (`Stream`, `CompletableFuture`, `Awaitable`), whose laws hold only up to observational equivalence and for which value equality is neither available nor expected.

As with `Associative` and `Reducer`, this annotation asserts that the carrier is lawful (the left/right identity and associativity laws); it does not prove it. The assertion is intended to be backed by tests.

Since:
  6.0.0

- ## Optional Element Summary

  Optional Elements
  Modifier and Type
  Optional Element
  Description
  `String`
  `bind`
  The flatMap-shaped bind method name.
  `String`
  `map`
  The map method name.
  `String`
  `unit`
  The name of the carrier's unit (a.k.a. `of`/`pure`/`return`) factory: a static, single-argument method that lifts a bare value into the carrier.

- ## Element Details

  - ### bind

    String bind
    The flatMap-shaped bind method name. Empty means the structural default `flatMap`.
    Default:
      ""

  - ### map

    String map
    The map method name. Empty means the structural default `map`.
    Default:
      ""

  - ### unit

    String unit
    The name of the carrier's unit (a.k.a. `of`/`pure`/`return`) factory: a static, single-argument method that lifts a bare value into the carrier. Empty means undeclared.

    The `DO` macro does not use this member — its body yields the carrier explicitly, so no implicit lifting is performed. Unlike `bind()` and `map()`, the unit cannot be recovered structurally: it is a producer (`value -> carrier`), commonly a static factory (for example `Optional.of`), and for a multi-case carrier several factories share that shape (an `Either`'s `left`/`right`). Naming it lets law-deriving or law-checking tooling synthesize the unit-dependent laws (left identity, right identity); the unit-free laws (associativity, the functor laws) do not need it. This is the `@Monadic` analogue of `Reducer.zero()`.

    Default:
      ""