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?

有帮助吗?

解决方案

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

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top