Search code examples
haskelloption-typealternative-functor

In Haskell, is there an abstraction for the <?>-operator?


I just found myself writing 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: pick the first alternative that is not empty and default to c. You can call it "reverse Maybe monad" where the analogy to <?> would be pure.

Equivalently, I could have written

Just x = mA <|> mB <|> pure c,

but I feel uncomfortable with the irrefutable pattern. Or, of course,

x = fromMaybe c (mA <|> mB)

because fromMaybe === flip <?>.

The <?> operator is inspired from parsec. I always get suspicious when I find myself defining utility functions like that, but I couldn't find this defaulting behavior anywhere.

Apparently Alternative and Applicative are not powerful enough.

Did I miss a type-class?


Solution

  • I think it's a good idea to leave things at (<?>) = flip fromMaybe.

    If you'd like to generalize though, Foldable seems to be the simplest class with a notion of emptiness:

    (<?>) :: Foldable t => t a -> a -> a
    ta <?> a = foldr const a ta 
    

    This returns a if ta is empty or else the first element of ta. Examples:

    Just 0 <?> 10 == 0
    Nothing <?> 0 == 0
    [] <?> 10 == 10