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?

+6
source share
3 answers

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 
+8
source

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.

+3
source

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.

+3
source

All Articles