com.jnape.palatable.lambda.monad

## Interface MonadRec<A,M extends MonadRec<?,M>>

- Type Parameters:
    `A` - the carrier type
    `M` - the `witness`
  All Superinterfaces:
    Applicative<A,M>, Functor<A,M>, Monad<A,M>
  All Known Subinterfaces:
    BiMonoidFactory<A,B,C>, BiPredicate<A,B>, BiSemigroupFactory<A,B,C>, Effect<A>, Fn0<A>, Fn1<A,B>, Fn2<A,B,C>, Fn3<A,B,C,D>, Fn4<A,B,C,D,E>, Fn5<A,B,C,D,E,F>, Fn6<A,B,C,D,E,F,G>, Fn7<A,B,C,D,E,F,G,H>, Fn8<A,B,C,D,E,F,G,H,I>, Iso<S,T,A,B>, Iso.Simple<S,A>, Kleisli<A,B,M,MB>, Lens<S,T,A,B>, Lens.Simple<S,A>, MonadT<M,A,MT,T>, Monoid<A>, MonoidFactory<A,B>, Predicate<A>, Prism<S,T,A,B>, Prism.Simple<S,A>, Schema<Values>, Semigroup<A>, SemigroupFactory<A,B>, TypeSafeKey<A,B>, TypeSafeKey.Simple<A>
  All Known Implementing Classes:
    Absent, AddAll, All, Alter, And, Any, AutoBracket, Between, Both, Bracket, CartesianProduct, CatMaybes, Choice2, Choice3, Choice4, Choice5, Choice6, Choice7, Choice8, Clamp, CmpEq, CmpEqBy, Coalesce, Collapse, Collapse, Compose, Compose, Concat, Cons, Const, Constantly, Cycle, Difference, Distinct, Downcast, Drop, DropWhile, Either, EitherT, Empty, Endo, EndoK, Eq, Filter, Find, First, Flatten, FoldLeft, FoldRight, Force, GroupBy, GT, GTBy, GTE, GTEBy, Head, Id, Identity, IdentityT, IfThenElse, InGroupsOf, Init, Inits, Intersection, Intersperse, Into, Into1, Into3, Into4, Into5, Into6, Into7, Into8, IO, Iterate, Join, LambdaIterable, Last, Last, Lazy, LazyRec, LazyT, LeftAll, LeftAll, LeftAny, LeftAny, LiftA2, LiftA3, LiftA4, LiftA5, LiftA6, LiftA7, LT, LTBy, LTE, LTEBy, Magnetize, MagnetizeBy, Map, Market, Matching, Max, MaxBy, Maybe, MaybeT, Merge, Merge, MergeMaps, Min, MinBy, Not, Occurrences, Or, Over, Partition, Peek, Peek2, Pre, PrependAll, Present, PutAll, RateLimit, Re, ReaderT, RecursiveResult, ReduceLeft, ReduceRight, Repeat, Replicate, Reverse, RightAll, RightAll, RightAny, RightAny, RunAll, RunAll, SafeT, ScanLeft, Sequence, Set, SingletonHList, Size, Slide, Snoc, Sort, SortBy, SortWith, Span, State, StateT, Tagged, Tail, Tails, Take, TakeWhile, These, Times, ToArray, ToCollection, ToMap, Trampoline, Trivial, Try, Tuple2, Tuple3, Tuple4, Tuple5, Tuple6, Tuple7, Tuple8, Tupler2, Uncons, Under, Unfoldr, Union, Until, Upcast, View, Writer, WriterT, Xor, Zip, ZipWith

      public interface MonadRec<A,M extends MonadRec<?,M>>
      extends Monad<A,M>

  A class of `monads` that offer a stack-safe interface for performing arbitrarily many `flatmap-like` operations via `trampolineM(Fn1)`.

  Inspired by Phil Freeman's paper _Stack Safety for Free_

- - ### Method Summary

    All Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method and Description
    --- | ---
    `default <B> MonadRec<B,M>` | `discardL(Applicative<B,M> appB)` Sequence both this `Applicative` and `appB`, discarding this `Applicative's` result and returning `appB`.
    `default <B> MonadRec<A,M>` | `discardR(Applicative<B,M> appB)` Sequence both this `Applicative` and `appB`, discarding `appB's` result and returning this `Applicative`.
    `<B> MonadRec<B,M>` | `flatMap(Fn1<? super A,? extends Monad<B,M>> f)` Chain dependent computations that may continue or short-circuit based on previous results.
    `default <B> MonadRec<B,M>` | `fmap(Fn1<? super A,? extends B> fn)` Covariantly transmute this functor's parameter using the given mapping function.
    `default <B> Lazy<? extends MonadRec<B,M>>` | `lazyZip(Lazy<? extends Applicative<Fn1<? super A,? extends B>,M>> lazyAppFn)` Given a `lazy` instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.
    `<B> MonadRec<B,M>` | `pure(B b)` Lift the value `b` into this applicative functor.
    `<B> MonadRec<B,M>` | `trampolineM(Fn1<? super A,? extends MonadRec<RecursiveResult<A,B>,M>> fn)` Given some operation yielding a `RecursiveResult` inside this `MonadRec`, internally trampoline the operation until it yields a `termination` instruction.
    `default <B> MonadRec<B,M>` | `zip(Applicative<Fn1<? super A,? extends B>,M> appFn)` Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.

    - ### Methods inherited from interface com.jnape.palatable.lambda.monad.Monad

      `join`

    - ### Methods inherited from interface com.jnape.palatable.lambda.functor.Functor

      `coerce`

- - ### Method Detail

    - #### trampolineM

          <B> MonadRec<B,M> trampolineM(Fn1<? super A,? extends MonadRec<RecursiveResult<A,B>,M>> fn)

      Given some operation yielding a `RecursiveResult` inside this `MonadRec`, internally trampoline the operation until it yields a `termination` instruction.

      Stack-safety depends on implementations guaranteeing that the growth of the call stack is a constant factor independent of the number of invocations of the operation. For various examples of how this can be achieved in stereotypical circumstances, see the referenced types.

      Type Parameters:
        `B` - the ultimate resulting carrier type
      Parameters:
        `fn` - the function to internally trampoline
      Returns:
        the trampolined `MonadRec`
      See Also:
        `for a basic implementation`, `for a {@link CoProduct2 coproduct} implementation`, `for an implementation leveraging an already stack-safe {@link Monad#flatMap(Fn1)}`, `for a {@link MonadT monad transformer} implementation`

    - #### flatMap

          <B> MonadRec<B,M> flatMap(Fn1<? super A,? extends Monad<B,M>> f)

      Chain dependent computations that may continue or short-circuit based on previous results.
      Specified by:
        `flatMap` in interface `Monad<A,M extends MonadRec<?,M>>`
      Type Parameters:
        `B` - the resulting monad parameter type
      Parameters:
        `f` - the dependent computation over A
      Returns:
        the new monad instance

    - #### pure

          <B> MonadRec<B,M> pure(B b)

      Lift the value `b` into this applicative functor.
      Specified by:
        `pure` in interface `Applicative<A,M extends MonadRec<?,M>>`
      Specified by:
        `pure` in interface `Monad<A,M extends MonadRec<?,M>>`
      Type Parameters:
        `B` - the type of the returned applicative's parameter
      Parameters:
        `b` - the value
      Returns:
        an instance of this applicative over b

    - #### fmap

          default <B> MonadRec<B,M> fmap(Fn1<? super A,? extends B> fn)

      Covariantly transmute this functor's parameter using the given mapping function. Generally this method is specialized to return an instance of the class implementing Functor.
      Specified by:
        `fmap` in interface `Applicative<A,M extends MonadRec<?,M>>`
      Specified by:
        `fmap` in interface `Functor<A,M extends MonadRec<?,M>>`
      Specified by:
        `fmap` in interface `Monad<A,M extends MonadRec<?,M>>`
      Type Parameters:
        `B` - the new parameter type
      Parameters:
        `fn` - the mapping function
      Returns:
        a functor over B (the new parameter type)

    - #### zip

          default <B> MonadRec<B,M> zip(Applicative<Fn1<? super A,? extends B>,M> appFn)

      Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.
      Specified by:
        `zip` in interface `Applicative<A,M extends MonadRec<?,M>>`
      Specified by:
        `zip` in interface `Monad<A,M extends MonadRec<?,M>>`
      Type Parameters:
        `B` - the resulting applicative parameter type
      Parameters:
        `appFn` - the other applicative instance
      Returns:
        the mapped applicative

    - #### lazyZip

          default <B> Lazy<? extends MonadRec<B,M>> lazyZip(Lazy<? extends Applicative<Fn1<? super A,? extends B>,M>> lazyAppFn)

      Given a `lazy` instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports. This is useful for applicatives that support lazy evaluation and early termination.
      Specified by:
        `lazyZip` in interface `Applicative<A,M extends MonadRec<?,M>>`
      Specified by:
        `lazyZip` in interface `Monad<A,M extends MonadRec<?,M>>`
      Type Parameters:
        `B` - the resulting applicative parameter type
      Parameters:
        `lazyAppFn` - the lazy other applicative instance
      Returns:
        the mapped applicative
      See Also:
        `Maybe`, `Either`

    - #### discardL

          default <B> MonadRec<B,M> discardL(Applicative<B,M> appB)

      Sequence both this `Applicative` and `appB`, discarding this `Applicative's` result and returning `appB`. This is generally useful for sequentially performing side-effects.
      Specified by:
        `discardL` in interface `Applicative<A,M extends MonadRec<?,M>>`
      Specified by:
        `discardL` in interface `Monad<A,M extends MonadRec<?,M>>`
      Type Parameters:
        `B` - the type of the returned Applicative's parameter
      Parameters:
        `appB` - the other Applicative
      Returns:
        appB

    - #### discardR

          default <B> MonadRec<A,M> discardR(Applicative<B,M> appB)

      Sequence both this `Applicative` and `appB`, discarding `appB's` result and returning this `Applicative`. This is generally useful for sequentially performing side-effects.
      Specified by:
        `discardR` in interface `Applicative<A,M extends MonadRec<?,M>>`
      Specified by:
        `discardR` in interface `Monad<A,M extends MonadRec<?,M>>`
      Type Parameters:
        `B` - the type of appB's parameter
      Parameters:
        `appB` - the other Applicative
      Returns:
        this Applicative