    {-# LANGUAGE CPP               #-}
    {-# LANGUAGE DeriveFunctor     #-}
    {-# LANGUAGE DeriveFoldable    #-}
    {-# LANGUAGE DeriveTraversable #-}

    -- | Use the `Optional` type for optional function arguments.  For example:
    --
    -- > import Data.Optional
    -- >
    -- > greet :: Optional String -> String
    -- > greet (Specific name) = "Hello, " ++ name
    -- > greet  Default        = "Hello"
    --
    -- >>> greet (Specific "John")
    -- "Hello, John"
    -- >>> greet Default
    -- "Hello"
    --
    --     The `Optional` type overloads as many Haskell literals as possible so
    --     that you do not need to wrap values in `Specific`.  For example, if you
    --     enable the `OverloadedStrings` extension you can use a naked string
    --     literal instead:
    --
    -- >>> :set -XOverloadedStrings
    -- >>> greet "John"
    -- "Hello, John"
    --
    --     The `Optional` type also implements `Num` and `Fractional`, so you can
    --     use numeric literals in place of `Optional` values:
    --
    -- > birthday :: Optional Int -> String
    -- > birthday (Specific age) = "You are " ++ show age ++ " years old!"
    -- > birthday  Default       = "You are one year older!"
    --
    -- >>> birthday 20
    -- "You are 20 years old!"
    -- >>> birthday Default
    -- "You are one year older!"
    --
    --     The `IsString`, `Num`, and `Fractional` instances are recursive, so you
    --     can wrap your types in a more descriptive newtype and derive `IsString`,
    --     `Num` or `Fractional`:
    --
    -- > {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    -- >
    -- > import Data.Optional
    -- > import Data.String (IsString)
    -- >
    -- > newtype Name = Name { getName :: String } deriving (IsString)
    -- >
    -- > greet :: Optional Name -> String
    -- > greet (Specific name) = "Hello, " ++ getName name
    -- > greet  Default        = "Hello"
    -- >
    -- > newtype Age = Age { getAge :: Int } deriving (Num)
    -- >
    -- > birthday :: Optional Age -> String
    -- > birthday (Specific age) = "You are " ++ show (getAge age) ++ " years old!"
    -- > birthday  Default       = "You are one year older!"
    --
    --     ... and you would still be able to provide naked numeric or string
    --     literals:
    --
    -- >>> :set -XOverloadedStrings
    -- >>> greet "John"
    -- "Hello, John"
    -- >>> birthday 20
    -- "You are 20 years old!"
    --
    --     You can use `empty` as a short-hand for a `Default` argument:
    --
    -- >>> greet empty
    -- "Hello"
    -- >>> birthday empty
    -- "You are one year older!"
    --
    --     You can also use `pure` as a short-hand for a `Specific` argument:
    --
    -- >>> greet (pure "John")
    -- "Hello, John"
    -- >>> birthday (pure 20)
    -- "You are 20 years old!"

    module Data.Optional (
        -- * Optional
          Optional(..)
        , defaultTo
        , fromOptional
        , optional

        -- * Re-exports
        , empty
        , pure
        ) where

    import Control.Applicative (Applicative(..), Alternative(..), liftA2)
    import Control.Monad (MonadPlus(..))
    import Data.Foldable (Foldable)
    import Data.Traversable (Traversable)
    import Data.Monoid (Monoid(..))
    import Data.Semigroup (Semigroup(..))
    import Data.String (IsString(..))

    -- | A function argument that has a `Default` value
    data Optional a = Default | Specific a
        deriving (Optional a -> Optional a -> Bool
    (Optional a -> Optional a -> Bool)
    -> (Optional a -> Optional a -> Bool) -> Eq (Optional a)
    forall a. Eq a => Optional a -> Optional a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => Optional a -> Optional a -> Bool
    == :: Optional a -> Optional a -> Bool
    $c/= :: forall a. Eq a => Optional a -> Optional a -> Bool
    /= :: Optional a -> Optional a -> Bool
    Eq, (forall a b. (a -> b) -> Optional a -> Optional b)
    -> (forall a b. a -> Optional b -> Optional a) -> Functor Optional
    forall a b. a -> Optional b -> Optional a
    forall a b. (a -> b) -> Optional a -> Optional b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> Optional a -> Optional b
    fmap :: forall a b. (a -> b) -> Optional a -> Optional b
    $c<$ :: forall a b. a -> Optional b -> Optional a
    <$ :: forall a b. a -> Optional b -> Optional a
    Functor, (forall m. Monoid m => Optional m -> m)
    -> (forall m a. Monoid m => (a -> m) -> Optional a -> m)
    -> (forall m a. Monoid m => (a -> m) -> Optional a -> m)
    -> (forall a b. (a -> b -> b) -> b -> Optional a -> b)
    -> (forall a b. (a -> b -> b) -> b -> Optional a -> b)
    -> (forall b a. (b -> a -> b) -> b -> Optional a -> b)
    -> (forall b a. (b -> a -> b) -> b -> Optional a -> b)
    -> (forall a. (a -> a -> a) -> Optional a -> a)
    -> (forall a. (a -> a -> a) -> Optional a -> a)
    -> (forall a. Optional a -> [a])
    -> (forall a. Optional a -> Bool)
    -> (forall a. Optional a -> Int)
    -> (forall a. Eq a => a -> Optional a -> Bool)
    -> (forall a. Ord a => Optional a -> a)
    -> (forall a. Ord a => Optional a -> a)
    -> (forall a. Num a => Optional a -> a)
    -> (forall a. Num a => Optional a -> a)
    -> Foldable Optional
    forall a. Eq a => a -> Optional a -> Bool
    forall a. Num a => Optional a -> a
    forall a. Ord a => Optional a -> a
    forall m. Monoid m => Optional m -> m
    forall a. Optional a -> Bool
    forall a. Optional a -> Int
    forall a. Optional a -> [a]
    forall a. (a -> a -> a) -> Optional a -> a
    forall m a. Monoid m => (a -> m) -> Optional a -> m
    forall b a. (b -> a -> b) -> b -> Optional a -> b
    forall a b. (a -> b -> b) -> b -> Optional a -> b
    forall (t :: * -> *).
    (forall m. Monoid m => t m -> m)
    -> (forall m a. Monoid m => (a -> m) -> t a -> m)
    -> (forall m a. Monoid m => (a -> m) -> t a -> m)
    -> (forall a b. (a -> b -> b) -> b -> t a -> b)
    -> (forall a b. (a -> b -> b) -> b -> t a -> b)
    -> (forall b a. (b -> a -> b) -> b -> t a -> b)
    -> (forall b a. (b -> a -> b) -> b -> t a -> b)
    -> (forall a. (a -> a -> a) -> t a -> a)
    -> (forall a. (a -> a -> a) -> t a -> a)
    -> (forall a. t a -> [a])
    -> (forall a. t a -> Bool)
    -> (forall a. t a -> Int)
    -> (forall a. Eq a => a -> t a -> Bool)
    -> (forall a. Ord a => t a -> a)
    -> (forall a. Ord a => t a -> a)
    -> (forall a. Num a => t a -> a)
    -> (forall a. Num a => t a -> a)
    -> Foldable t
    $cfold :: forall m. Monoid m => Optional m -> m
    fold :: forall m. Monoid m => Optional m -> m
    $cfoldMap :: forall m a. Monoid m => (a -> m) -> Optional a -> m
    foldMap :: forall m a. Monoid m => (a -> m) -> Optional a -> m
    $cfoldMap' :: forall m a. Monoid m => (a -> m) -> Optional a -> m
    foldMap' :: forall m a. Monoid m => (a -> m) -> Optional a -> m
    $cfoldr :: forall a b. (a -> b -> b) -> b -> Optional a -> b
    foldr :: forall a b. (a -> b -> b) -> b -> Optional a -> b
    $cfoldr' :: forall a b. (a -> b -> b) -> b -> Optional a -> b
    foldr' :: forall a b. (a -> b -> b) -> b -> Optional a -> b
    $cfoldl :: forall b a. (b -> a -> b) -> b -> Optional a -> b
    foldl :: forall b a. (b -> a -> b) -> b -> Optional a -> b
    $cfoldl' :: forall b a. (b -> a -> b) -> b -> Optional a -> b
    foldl' :: forall b a. (b -> a -> b) -> b -> Optional a -> b
    $cfoldr1 :: forall a. (a -> a -> a) -> Optional a -> a
    foldr1 :: forall a. (a -> a -> a) -> Optional a -> a
    $cfoldl1 :: forall a. (a -> a -> a) -> Optional a -> a
    foldl1 :: forall a. (a -> a -> a) -> Optional a -> a
    $ctoList :: forall a. Optional a -> [a]
    toList :: forall a. Optional a -> [a]
    $cnull :: forall a. Optional a -> Bool
    null :: forall a. Optional a -> Bool
    $clength :: forall a. Optional a -> Int
    length :: forall a. Optional a -> Int
    $celem :: forall a. Eq a => a -> Optional a -> Bool
    elem :: forall a. Eq a => a -> Optional a -> Bool
    $cmaximum :: forall a. Ord a => Optional a -> a
    maximum :: forall a. Ord a => Optional a -> a
    $cminimum :: forall a. Ord a => Optional a -> a
    minimum :: forall a. Ord a => Optional a -> a
    $csum :: forall a. Num a => Optional a -> a
    sum :: forall a. Num a => Optional a -> a
    $cproduct :: forall a. Num a => Optional a -> a
    product :: forall a. Num a => Optional a -> a
    Foldable, Functor Optional
    Foldable Optional
    (Functor Optional, Foldable Optional) =>
    (forall (f :: * -> *) a b.
     Applicative f =>
     (a -> f b) -> Optional a -> f (Optional b))
    -> (forall (f :: * -> *) a.
        Applicative f =>
        Optional (f a) -> f (Optional a))
    -> (forall (m :: * -> *) a b.
        Monad m =>
        (a -> m b) -> Optional a -> m (Optional b))
    -> (forall (m :: * -> *) a.
        Monad m =>
        Optional (m a) -> m (Optional a))
    -> Traversable Optional
    forall (t :: * -> *).
    (Functor t, Foldable t) =>
    (forall (f :: * -> *) a b.
     Applicative f =>
     (a -> f b) -> t a -> f (t b))
    -> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
    -> (forall (m :: * -> *) a b.
        Monad m =>
        (a -> m b) -> t a -> m (t b))
    -> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
    -> Traversable t
    forall (m :: * -> *) a. Monad m => Optional (m a) -> m (Optional a)
    forall (f :: * -> *) a.
    Applicative f =>
    Optional (f a) -> f (Optional a)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Optional a -> m (Optional b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Optional a -> f (Optional b)
    $ctraverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Optional a -> f (Optional b)
    traverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Optional a -> f (Optional b)
    $csequenceA :: forall (f :: * -> *) a.
    Applicative f =>
    Optional (f a) -> f (Optional a)
    sequenceA :: forall (f :: * -> *) a.
    Applicative f =>
    Optional (f a) -> f (Optional a)
    $cmapM :: forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Optional a -> m (Optional b)
    mapM :: forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Optional a -> m (Optional b)
    $csequence :: forall (m :: * -> *) a. Monad m => Optional (m a) -> m (Optional a)
    sequence :: forall (m :: * -> *) a. Monad m => Optional (m a) -> m (Optional a)
    Traversable, Int -> Optional a -> ShowS
    [Optional a] -> ShowS
    Optional a -> String
    (Int -> Optional a -> ShowS)
    -> (Optional a -> String)
    -> ([Optional a] -> ShowS)
    -> Show (Optional a)
    forall a. Show a => Int -> Optional a -> ShowS
    forall a. Show a => [Optional a] -> ShowS
    forall a. Show a => Optional a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> Optional a -> ShowS
    showsPrec :: Int -> Optional a -> ShowS
    $cshow :: forall a. Show a => Optional a -> String
    show :: Optional a -> String
    $cshowList :: forall a. Show a => [Optional a] -> ShowS
    showList :: [Optional a] -> ShowS
    Show)

    instance Applicative Optional where
        pure :: forall a. a -> Optional a
    pure = a -> Optional a
    forall a. a -> Optional a
    Specific

        Specific a -> b
    f <*> :: forall a b. Optional (a -> b) -> Optional a -> Optional b
    <*> Specific a
    x = b -> Optional b
    forall a. a -> Optional a
    Specific (a -> b
    f a
    x)
        Optional (a -> b)
    _          <*> Optional a
    _          = Optional b
    forall a. Optional a
    Default

    instance Monad Optional where
        return :: forall a. a -> Optional a
    return = a -> Optional a
    forall a. a -> Optional a
    Specific

        Optional a
    Default    >>= :: forall a b. Optional a -> (a -> Optional b) -> Optional b
    >>= a -> Optional b
    _ = Optional b
    forall a. Optional a
    Default
        Specific a
    x >>= a -> Optional b
    f = a -> Optional b
    f a
    x

    instance Alternative Optional where
        empty :: forall a. Optional a
    empty = Optional a
    forall a. Optional a
    Default

        Optional a
    Default <|> :: forall a. Optional a -> Optional a -> Optional a
    <|> Optional a
    x = Optional a
    x
        Optional a
    x       <|> Optional a
    _ = Optional a
    x

    instance MonadPlus Optional where
        mzero :: forall a. Optional a
    mzero = Optional a
    forall a. Optional a
    forall (f :: * -> *) a. Alternative f => f a
    empty
        mplus :: forall a. Optional a -> Optional a -> Optional a
    mplus = Optional a -> Optional a -> Optional a
    forall a. Optional a -> Optional a -> Optional a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    (<|>)

    instance Semigroup a => Semigroup (Optional a) where
        <> :: Optional a -> Optional a -> Optional a
    (<>) = (a -> a -> a) -> Optional a -> Optional a -> Optional a
    forall a b c.
    (a -> b -> c) -> Optional a -> Optional b -> Optional c
    forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 a -> a -> a
    forall a. Semigroup a => a -> a -> a
    (<>)

    instance Monoid a => Monoid (Optional a) where
        mempty :: Optional a
    mempty = a -> Optional a
    forall a. a -> Optional a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    forall a. Monoid a => a
    mempty

    #if !(MIN_VERSION_base(4,11,0))
        mappend = liftA2 mappend
    #endif

    instance IsString a => IsString (Optional a) where
        fromString :: String -> Optional a
    fromString String
    str = a -> Optional a
    forall a. a -> Optional a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (String -> a
    forall a. IsString a => String -> a
    fromString String
    str)

    instance Num a => Num (Optional a) where
        fromInteger :: Integer -> Optional a
    fromInteger Integer
    n = a -> Optional a
    forall a. a -> Optional a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    n)

        + :: Optional a -> Optional a -> Optional a
    (+) = (a -> a -> a) -> Optional a -> Optional a -> Optional a
    forall a b c.
    (a -> b -> c) -> Optional a -> Optional b -> Optional c
    forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 a -> a -> a
    forall a. Num a => a -> a -> a
    (+)
        * :: Optional a -> Optional a -> Optional a
    (*) = (a -> a -> a) -> Optional a -> Optional a -> Optional a
    forall a b c.
    (a -> b -> c) -> Optional a -> Optional b -> Optional c
    forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 a -> a -> a
    forall a. Num a => a -> a -> a
    (*)
        (-) = (a -> a -> a) -> Optional a -> Optional a -> Optional a
    forall a b c.
    (a -> b -> c) -> Optional a -> Optional b -> Optional c
    forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 (-)

        negate :: Optional a -> Optional a
    negate = (a -> a) -> Optional a -> Optional a
    forall a b. (a -> b) -> Optional a -> Optional b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> a
    forall a. Num a => a -> a
    negate
        abs :: Optional a -> Optional a
    abs    = (a -> a) -> Optional a -> Optional a
    forall a b. (a -> b) -> Optional a -> Optional b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> a
    forall a. Num a => a -> a
    abs
        signum :: Optional a -> Optional a
    signum = (a -> a) -> Optional a -> Optional a
    forall a b. (a -> b) -> Optional a -> Optional b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> a
    forall a. Num a => a -> a
    signum

    instance Fractional a => Fractional (Optional a) where
        fromRational :: Rational -> Optional a
    fromRational Rational
    n = a -> Optional a
    forall a. a -> Optional a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Rational -> a
    forall a. Fractional a => Rational -> a
    fromRational Rational
    n)

        recip :: Optional a -> Optional a
    recip = (a -> a) -> Optional a -> Optional a
    forall a b. (a -> b) -> Optional a -> Optional b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> a
    forall a. Fractional a => a -> a
    recip

        / :: Optional a -> Optional a -> Optional a
    (/) = (a -> a -> a) -> Optional a -> Optional a -> Optional a
    forall a b c.
    (a -> b -> c) -> Optional a -> Optional b -> Optional c
    forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 a -> a -> a
    forall a. Fractional a => a -> a -> a
    (/)

    -- | The 'optional' function takes a default value, a function, and an
    -- 'Optional' value. If the 'Optional' value is 'Default', the function returns
    -- the default value. Otherwise, it applies the function to the value inside the
    -- 'Optional' and returns the result.
    optional :: b -> (a -> b) -> Optional a -> b
    optional :: forall b a. b -> (a -> b) -> Optional a -> b
    optional b
    n a -> b
    _ Optional a
    Default      = b
    n
    optional b
    _ a -> b
    f (Specific a
    x) = a -> b
    f a
    x

    -- | The 'defaultTo' function takes a default value and an 'Optional'
    -- value.  If the 'Optional' is 'Default', it returns the default value;
    -- otherwise, it returns the value contained in the 'Optional'.
    defaultTo :: a -> Optional a -> a
    defaultTo :: forall a. a -> Optional a -> a
    defaultTo a
    d Optional a
    Default      = a
    d
    defaultTo a
    _ (Specific a
    v) = a
    v

    -- | Convert an 'Optional' value into an instance of 'Alternative'.
    fromOptional :: Alternative f => Optional a -> f a
    fromOptional :: forall (f :: * -> *) a. Alternative f => Optional a -> f a
    fromOptional  Optional a
    Default     = f a
    forall a. f a
    forall (f :: * -> *) a. Alternative f => f a
    empty
    fromOptional (Specific a
    x) = a -> f a
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    x