Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 971
ruben.moor Avatar asked Aug 29 '16 08:08

ruben.moor


1 Answers

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
like image 131
András Kovács Avatar answered Nov 10 '22 09:11

András Kovács