Using scala for reference, we see a fallback behavior (orElse) in several places such as PartialFunction, Option, and cats EitherOps.
This feels similar to but not the same as the flattening behavior of a monad. Is there a functional programming term for things that exhibit this behavior?
Edit: Some good answers so far, digging around more in cats, I've found
Semigroup[Option[String]].combine(None, Some("b"))
res0: Option[String] = Some(b)
Semigroup[Option[String]].combine(Some("a"), Some("b"))
res1: Option[String] = Some(ab)
SemigroupK[Option].combineK(None, Some("b"))
res2: Option[String] = Some(b)
SemigroupK[Option].combineK(Some("a"), Some("b"))
res3: Option[String] = Some(a)
SemigroupK[List].combineK(List("a"), List("b"))
res4: List[String] = List(a, b)
Alternative[List].unite(List(None, Some("a"), Some("b")))
res4: List[String] = List(a, b)
So I see now that the scalaz Alt and haskell Alternative are not quite the same as the cats Alternative. The more interesting thing is the SemigroupK (called Plus in scalaz according to the cats documentation).
So could we say this behavior is exhibited by a type for which you cannot define a semigroup without also having a semigroup for its inner type (because then we might say the scalaz Alt and haskell Alternative are semigroups for such kinds)?
A decent chunk of Scala is inspired by similar concepts in Haskell. In this particular case,
orElseis pretty close to the "alternative" operator<|>in theAlternativetypeclass.In Haskell, an
Applicativeis aFunctor(read: it contains things and has some way of interacting with those things) which has some meaningful monoidal way of "combining" those things:<*>. We can think of<*>as being somewhat similar (although not identical) to Scala'sandThen, in that it takes two "successful" computations and sequences them. Under this analogy, anAlternativeis anApplicativethat provides a way to "recover" from failure, so<|>is more or less Scala'sorElse.Since you mentioned monads,
Applicativeis a weakening ofMonad, in the sense that everyMonadis anApplicativebut not everyApplicativeis necessarilyMonad. For example, multidimensional arrays can easily be made intoApplicativebut cannot be madeMonad.So, to summarize, I believe the term you're looking for is "applicative functor with alternative capabilities", codified in Haskell by the
Alternativetypeclass. If you want to sound terribly arrogant, we can call it by its mathematically rigorous name: a strong lax monoidal functor backed by an additional monoidal structure. But that's just if we're showing off.