    {-# LANGUAGE CPP                #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveFunctor      #-}
    {-# LANGUAGE DeriveFoldable     #-}
    {-# LANGUAGE DeriveTraversable  #-}
    {-# LANGUAGE TypeOperators      #-}
    {-# OPTIONS_HADDOCK not-home    #-}
    module Servant.API.Alternative ((:<|>)(..)) where

    import           Data.Semigroup   (Semigroup (..))
    import           Data.Typeable    (Typeable)
    import           Prelude ()
    import           Prelude.Compat

    -- | Union of two APIs, first takes precedence in case of overlap.
    --
    -- Example:
    --
    -- >>> :{
    --type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
    --        :<|> "books" :> ReqBody '[JSON] Book :> Post '[JSON] () -- POST /books
    -- :}
    data a :<|> b = a :<|> b
        deriving (Typeable, Eq, Show, Functor, Traversable, Foldable, Bounded)
    infixr 8 :<|>

    instance (Semigroup a, Semigroup b) => Semigroup (a :<|> b) where
        (a :<|> b) <> (a' :<|> b') = (a <> a') :<|> (b <> b')

    instance (Monoid a, Monoid b) => Monoid (a :<|> b) where
        mempty = mempty :<|> mempty
        (a :<|> b) `mappend` (a' :<|> b') = (a `mappend` a') :<|> (b `mappend` b')

    -- $setup
    -- >>> import Servant.API
    -- >>> import Data.Aeson
    -- >>> import Data.Text
    -- >>> data Book
    -- >>> instance ToJSON Book where { toJSON = undefined }