Haskell has an abstraction for the <?>? Operator
I just wrote this code:
import Control.Applicative ((<|>)) x = mA <|> mB <?> c (<?>) :: Maybe a -> a -> a Just x <?> _ = x Nothing <?> y = y Where mA :: Maybe a , mB :: Maybe a , c :: a and x :: a . Basically, the code says: select the first option, which is not empty , but the default is c . You can call it "reverse Maybe monad", where the analogy with <?> Will be pure .
Equivalently, I could write
Just x = mA <|> mB <|> pure c, but I feel uncomfortable with an irrefutable picture. Or of course
x = fromMaybe c (mA <|> mB) because fromMaybe === flip <?> .
The operator <?> Is inspired by the parsec. I always become suspicious when I discover that I define utility functions like this, but I could not find this default behavior.
Alternative and Applicative apparently not powerful enough.
Am I missing a type class?
I think it's nice to leave things at (<?>) = flip fromMaybe .
If you want to generalize though, Foldable seems to be the simplest class with the concept of void:
(<?>) :: Foldable t => ta -> a -> a ta <?> a = foldr const a ta This returns a if ta empty or the first element is ta . Examples:
Just 0 <?> 10 == 0 Nothing <?> 0 == 0 [] <?> 10 == 10 Only two abstractions of "emptiness" that I can imagine on my head:
First, MonadError : Maybe may have instance MonadError () Maybe . See However, https://github.com/ekmett/mtl/issues/27
Secondly, lens _Empty , which by default is compared ( Eq ) to mempty (from Monoid ). However, Monoid and Alternative disagree for Maybe .
However, I do not remember that any operator worked directly on one of them.
Actually, I don't like the name of the <?> Operator for what you are looking for. If you are looking for the Maybe a -> a -> a on Stackage or Hayoo, you can find the ?: Operator from the errors package.
And this operator is called the so-called elvis-operator. It is used at Groovy in this form. And Kotlin also had this. This operator helps deal with zeros in an imperative language. But if you imagine that Maybe a is some type with a zero value, then the ?: Operator makes sense for you. You may notice that behind the ?: Operator there is some history.
In addition, <?> already used in some packages, such as megaparsec , attoparsec , optparse-generic and others. And your project may use one of them with a high probability. Thus, you may encounter some conflicts using your version of the elvis operator.