Reputation: 5297
I want to easily take a value out of a "failable" data type or use a default in the case of failure.
Here's my implementation for Maybe
:
infixr 1 <||>
(<||>) :: Maybe a -> a -> a
(<||>) = flip fromMaybe
pred :: String -> String -> Bool
pred x name = (x ==) <$> name `lookup` myMap <||> False
pred
returns True
if name
maps to x
in myMap
.
But as is usually the case in Haskell, there is a more abstract way of doing this that I am unaware of. Anyone?
Upvotes: 0
Views: 108
Reputation: 5297
Here's what I came up with:
class Defaultable f where
infixr 1 <||>
(<||>) :: f a -> a -> a
instance Defaultable Maybe where
(<||>) = flip fromMaybe
instance Defaultable (Either a) where
(Left _) <||> x = x
(Right x) <||> _ = x
Coupled with Alternative
, you can string together possible choices with a default at the end.
Upvotes: 0
Reputation: 29100
Foldable
is probably a reasonable choice from the standard libraries:
import Data.Foldable
infixr 1 <||>
(<||>) :: Foldable f => f a -> a -> a
v <||> a =
case toList v of
[] -> a
(x:xs) -> x
It does mean you have to decide whether to take the "first" element found or the "last" one though. Also unfortunately it doesn't yet have an Either
instance, though it's coming in GHC 7.8/base 4.7. In the meantime you can define it yourself:
instance Foldable (Either a) where
foldMap _ (Left _) = mempty
foldMap f (Right y) = f y
foldr _ z (Left _) = z
foldr f z (Right y) = f y z
Upvotes: 4