    {-# LANGUAGE ApplicativeDo #-}
    {-# LANGUAGE EmptyCase #-}

    -- | MultiVerb is a part of the type-level eDSL that allows you to express complex routes
    -- while retaining a high level of precision with good ergonomics.

    module Servant.API.MultiVerb
      ( -- ** MultiVerb types
        MultiVerb,
        MultiVerb1,
        -- ** Response types
        Respond,
        RespondAs,
        RespondEmpty,
        RespondStreaming,
        -- ** Headers
        WithHeaders,
        DescHeader,
        OptHeader,
        AsHeaders (..),
        ServantHeaders(..),
        ServantHeader(..),
        -- ** Unions of responses
        AsUnion (..),
        eitherToUnion,
        eitherFromUnion,
        maybeToUnion,
        maybeFromUnion,
        -- ** Internal machinery
        AsConstructor (..),
        GenericAsConstructor (..),
        GenericAsUnion (..),
        ResponseType,
        ResponseTypes,
        UnrenderResult(..),
      ) where

    import Control.Applicative (Alternative(..), empty)
    import Control.Monad (ap, MonadPlus(..))
    import Data.ByteString (ByteString)
    import Data.Kind
    import Data.Proxy
    import Data.SOP
    import Data.Sequence (Seq(..))
    import GHC.TypeLits
    import Generics.SOP as GSOP
    import Network.HTTP.Types as HTTP
    import Web.HttpApiData (FromHttpApiData, ToHttpApiData, parseHeader, toHeader)
    import qualified Data.CaseInsensitive as CI
    import qualified Data.Sequence as Seq
    import qualified Data.Text as Text
    import qualified Data.Text.Encoding as Text

    import Servant.API.TypeLevel.List
    import Servant.API.Stream (SourceIO)
    import Servant.API.UVerb.Union (Union)
    import Servant.API.Header (Header')

    -- | A type to describe a 'MultiVerb' response.
    --
    -- Includes status code, description, and return type. The content type of the
    -- response is determined dynamically using the accept header and the list of
    -- supported content types specified in the containing 'MultiVerb' type.
    data Respond (s :: Nat) (description :: Symbol) (a :: Type)

    -- | A type to describe a 'MultiVerb' response with a fixed content type.
    --
    -- Similar to 'Respond', but hardcodes the content type to be used for
    -- generating the response. This content type is distinct from the one
    -- given to 'MultiVerb', as it dictactes the response's content type, not the
    -- content type request that is to be accepted.
    data RespondAs responseContentType (s :: Nat) (description :: Symbol) (a :: Type)

    -- | A type to describe a 'MultiVerb' response with an empty body.
    --
    -- Includes status code and description.
    type RespondEmpty s description = RespondAs '() s description ()

    -- | A type to describe a streaming 'MultiVerb' response.
    --
    -- Includes status code, description, framing strategy and content type. Note
    -- that the handler return type is hardcoded to be 'SourceIO ByteString'.
    data RespondStreaming (s :: Nat) (description :: Symbol) (framing :: Type) (ct :: Type)

    -- | The result of parsing a response as a union alternative of type 'a'.
    --
    -- 'StatusMismatch' indicates that the response does not refer to the given
    -- alternative, because the status code does not match the one produced by that
    -- alternative.
    --
    -- 'UnrenderError' and 'UnrenderSuccess' represent respectively a failing and
    -- successful parse of the response body as a value of type 'a'.
    --
    -- The 'UnrenderResult' type constructor has monad and alternative instances
    -- corresponding to those of 'Either (Maybe (Last String)) a'.
    data UnrenderResult a = StatusMismatch | UnrenderError String | UnrenderSuccess a
      deriving (UnrenderResult a -> UnrenderResult a -> Bool
    (UnrenderResult a -> UnrenderResult a -> Bool)
    -> (UnrenderResult a -> UnrenderResult a -> Bool)
    -> Eq (UnrenderResult a)
    forall a. Eq a => UnrenderResult a -> UnrenderResult a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => UnrenderResult a -> UnrenderResult a -> Bool
    == :: UnrenderResult a -> UnrenderResult a -> Bool
    $c/= :: forall a. Eq a => UnrenderResult a -> UnrenderResult a -> Bool
    /= :: UnrenderResult a -> UnrenderResult a -> Bool
    Eq, Int -> UnrenderResult a -> ShowS
    [UnrenderResult a] -> ShowS
    UnrenderResult a -> String
    (Int -> UnrenderResult a -> ShowS)
    -> (UnrenderResult a -> String)
    -> ([UnrenderResult a] -> ShowS)
    -> Show (UnrenderResult a)
    forall a. Show a => Int -> UnrenderResult a -> ShowS
    forall a. Show a => [UnrenderResult a] -> ShowS
    forall a. Show a => UnrenderResult a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> UnrenderResult a -> ShowS
    showsPrec :: Int -> UnrenderResult a -> ShowS
    $cshow :: forall a. Show a => UnrenderResult a -> String
    show :: UnrenderResult a -> String
    $cshowList :: forall a. Show a => [UnrenderResult a] -> ShowS
    showList :: [UnrenderResult a] -> ShowS
    Show, (forall a b. (a -> b) -> UnrenderResult a -> UnrenderResult b)
    -> (forall a b. a -> UnrenderResult b -> UnrenderResult a)
    -> Functor UnrenderResult
    forall a b. a -> UnrenderResult b -> UnrenderResult a
    forall a b. (a -> b) -> UnrenderResult a -> UnrenderResult b
    forall (f :: Type -> Type).
    (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) -> UnrenderResult a -> UnrenderResult b
    fmap :: forall a b. (a -> b) -> UnrenderResult a -> UnrenderResult b
    $c<$ :: forall a b. a -> UnrenderResult b -> UnrenderResult a
    <$ :: forall a b. a -> UnrenderResult b -> UnrenderResult a
    Functor)

    instance Applicative UnrenderResult where
      pure :: forall a. a -> UnrenderResult a
    pure = a -> UnrenderResult a
    forall a. a -> UnrenderResult a
    UnrenderSuccess
      <*> :: forall a b.
    UnrenderResult (a -> b) -> UnrenderResult a -> UnrenderResult b
    (<*>) = UnrenderResult (a -> b) -> UnrenderResult a -> UnrenderResult b
    forall (m :: Type -> Type) a b. Monad m => m (a -> b) -> m a -> m b
    ap

    instance Monad UnrenderResult where
      return :: forall a. a -> UnrenderResult a
    return = a -> UnrenderResult a
    forall a. a -> UnrenderResult a
    forall (f :: Type -> Type) a. Applicative f => a -> f a
    pure
      UnrenderResult a
    StatusMismatch >>= :: forall a b.
    UnrenderResult a -> (a -> UnrenderResult b) -> UnrenderResult b
    >>= a -> UnrenderResult b
    _ = UnrenderResult b
    forall a. UnrenderResult a
    StatusMismatch
      UnrenderError String
    e >>= a -> UnrenderResult b
    _ = String -> UnrenderResult b
    forall a. String -> UnrenderResult a
    UnrenderError String
    e
      UnrenderSuccess a
    x >>= a -> UnrenderResult b
    f = a -> UnrenderResult b
    f a
    x

    instance Alternative UnrenderResult where
      empty :: forall a. UnrenderResult a
    empty = UnrenderResult a
    forall a. UnrenderResult a
    forall (m :: Type -> Type) a. MonadPlus m => m a
    mzero
      <|> :: forall a. UnrenderResult a -> UnrenderResult a -> UnrenderResult a
    (<|>) = UnrenderResult a -> UnrenderResult a -> UnrenderResult a
    forall a. UnrenderResult a -> UnrenderResult a -> UnrenderResult a
    forall (m :: Type -> Type) a. MonadPlus m => m a -> m a -> m a
    mplus

    instance MonadPlus UnrenderResult where
      mzero :: forall a. UnrenderResult a
    mzero = UnrenderResult a
    forall a. UnrenderResult a
    StatusMismatch
      mplus :: forall a. UnrenderResult a -> UnrenderResult a -> UnrenderResult a
    mplus UnrenderResult a
    StatusMismatch UnrenderResult a
    m = UnrenderResult a
    m
      mplus (UnrenderError String
    e) UnrenderResult a
    StatusMismatch = String -> UnrenderResult a
    forall a. String -> UnrenderResult a
    UnrenderError String
    e
      mplus (UnrenderError String
    _) UnrenderResult a
    m = UnrenderResult a
    m
      mplus m :: UnrenderResult a
    m@(UnrenderSuccess a
    _) UnrenderResult a
    _ = UnrenderResult a
    m

    type family ResponseType a :: Type

    type instance ResponseType (Respond s description a) = a

    type instance ResponseType (RespondAs responseContentType s description a) = a

    type instance ResponseType (RespondStreaming s description framing ct) = SourceIO ByteString

    -- | This type adds response headers to a 'MultiVerb' response.
    data WithHeaders (headers :: [Type]) (returnType :: Type) (response :: Type)

    -- | This is used to convert a response containing headers to a custom type
    -- including the information in the headers.
    --
    -- If you need to send a combination of headers and response that is not provided by Servant,
    -- you can cwrite your own instance. Take example on the ones provided.
    class AsHeaders headers response returnType where
      fromHeaders :: (NP I headers, response) -> returnType
      toHeaders :: returnType -> (NP I headers, response)

    -- | Single-header empty response
    instance AsHeaders '[a] () a where
      toHeaders :: a -> (NP I '[a], ())
    toHeaders a
    a = (a -> I a
    forall a. a -> I a
    I a
    a I a -> NP I '[] -> NP I '[a]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NP a xs -> NP a (x : xs)
    :* NP I '[]
    forall {k} (a :: k -> Type). NP a '[]
    Nil, ())
      fromHeaders :: (NP I '[a], ()) -> a
    fromHeaders = I a -> a
    forall a. I a -> a
    unI (I a -> a) -> ((NP I '[a], ()) -> I a) -> (NP I '[a], ()) -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NP I '[a] -> I a
    forall {k} (f :: k -> Type) (x :: k) (xs :: [k]).
    NP f (x : xs) -> f x
    hd (NP I '[a] -> I a)
    -> ((NP I '[a], ()) -> NP I '[a]) -> (NP I '[a], ()) -> I a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (NP I '[a], ()) -> NP I '[a]
    forall a b. (a, b) -> a
    fst

    -- | Single-header non-empty response, return value is a tuple of the response and the header
    instance AsHeaders '[h] a (a, h) where
      toHeaders :: (a, h) -> (NP I '[h], a)
    toHeaders (a
    t, h
    cc) = (h -> I h
    forall a. a -> I a
    I h
    cc I h -> NP I '[] -> NP I '[h]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NP a xs -> NP a (x : xs)
    :* NP I '[]
    forall {k} (a :: k -> Type). NP a '[]
    Nil, a
    t)
      fromHeaders :: (NP I '[h], a) -> (a, h)
    fromHeaders (I x
    cc :* NP I xs
    Nil, a
    t) = (a
    t, h
    x
    cc)

    -- | Two headers and an empty response, return value is a tuple of the response and the header
    instance AsHeaders '[a, b] () (a, b) where
      toHeaders :: (a, b) -> (NP I '[a, b], ())
    toHeaders (a
    h1, b
    h2) = (a -> I a
    forall a. a -> I a
    I a
    h1 I a -> NP I '[b] -> NP I '[a, b]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NP a xs -> NP a (x : xs)
    :* b -> I b
    forall a. a -> I a
    I b
    h2 I b -> NP I '[] -> NP I '[b]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NP a xs -> NP a (x : xs)
    :* NP I '[]
    forall {k} (a :: k -> Type). NP a '[]
    Nil, ())
      fromHeaders :: (NP I '[a, b], ()) -> (a, b)
    fromHeaders (I x
    h1 :* I x
    h2 :* NP I xs
    Nil, ()) = (a
    x
    h1, b
    x
    h2)

    data DescHeader (name :: Symbol) (description :: Symbol) (a :: Type)

    -- | A wrapper to turn a response header into an optional one.
    data OptHeader h

    class ServantHeaders headers xs | headers -> xs where
      constructHeaders :: NP I xs -> [HTTP.Header]
      extractHeaders :: Seq HTTP.Header -> Maybe (NP I xs)

    instance ServantHeaders '[] '[] where
      constructHeaders :: NP I '[] -> [Header]
    constructHeaders NP I '[]
    Nil = []
      extractHeaders :: Seq Header -> Maybe (NP I '[])
    extractHeaders Seq Header
    _ = NP I '[] -> Maybe (NP I '[])
    forall a. a -> Maybe a
    Just NP I '[]
    forall {k} (a :: k -> Type). NP a '[]
    Nil

    headerName :: forall name. (KnownSymbol name) => HTTP.HeaderName
    headerName :: forall (name :: Symbol). KnownSymbol name => HeaderName
    headerName =
      ByteString -> HeaderName
    forall s. FoldCase s => s -> CI s
    CI.mk
        (ByteString -> HeaderName)
    -> (String -> ByteString) -> String -> HeaderName
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> ByteString
    Text.encodeUtf8
        (Text -> ByteString) -> (String -> Text) -> String -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    Text.pack
        (String -> HeaderName) -> String -> HeaderName
    forall a b. (a -> b) -> a -> b
    $ Proxy name -> String
    forall (n :: Symbol) (proxy :: Symbol -> Type).
    KnownSymbol n =>
    proxy n -> String
    symbolVal (forall {k} (t :: k). Proxy t
    forall (t :: Symbol). Proxy t
    Proxy @name)

    instance
      ( KnownSymbol name,
        ServantHeader h name x,
        FromHttpApiData x,
        ServantHeaders headers xs
      ) =>
      ServantHeaders (h ': headers) (x ': xs)
      where
      constructHeaders :: NP I (x : xs) -> [Header]
    constructHeaders (I x
    x :* NP I xs
    xs) =
        forall (h :: a) (name :: Symbol) x.
    ServantHeader h name x =>
    x -> [Header]
    forall {k} (h :: k) (name :: Symbol) x.
    ServantHeader h name x =>
    x -> [Header]
    constructHeader @h x
    x
          [Header] -> [Header] -> [Header]
    forall a. Semigroup a => a -> a -> a
    <> forall (headers :: [a]) (xs :: [Type]).
    ServantHeaders headers xs =>
    NP I xs -> [Header]
    forall {k} (headers :: k) (xs :: [Type]).
    ServantHeaders headers xs =>
    NP I xs -> [Header]
    constructHeaders @headers NP I xs
    xs

      -- NOTE: should we concatenate all the matching headers instead of just taking the first one?
      extractHeaders :: Seq Header -> Maybe (NP I (x : xs))
    extractHeaders Seq Header
    headers = do
        let name' :: HeaderName
    name' = forall (name :: Symbol). KnownSymbol name => HeaderName
    headerName @name
            (Seq Header
    headers0, Seq Header
    headers1) = (Header -> Bool) -> Seq Header -> (Seq Header, Seq Header)
    forall a. (a -> Bool) -> Seq a -> (Seq a, Seq a)
    Seq.partition (\(HeaderName
    h, ByteString
    _) -> HeaderName
    h HeaderName -> HeaderName -> Bool
    forall a. Eq a => a -> a -> Bool
    == HeaderName
    name') Seq Header
    headers
        x
    x <- case Seq Header
    headers0 of
          Seq Header
    Seq.Empty -> Maybe x
    forall a. Maybe a
    forall (f :: Type -> Type) a. Alternative f => f a
    empty
          ((HeaderName
    _, ByteString
    h) :<| Seq Header
    _) -> (Text -> Maybe x) -> (x -> Maybe x) -> Either Text x -> Maybe x
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe x -> Text -> Maybe x
    forall a b. a -> b -> a
    const Maybe x
    forall a. Maybe a
    forall (f :: Type -> Type) a. Alternative f => f a
    empty) x -> Maybe x
    forall a. a -> Maybe a
    forall (f :: Type -> Type) a. Applicative f => a -> f a
    pure (ByteString -> Either Text x
    forall a. FromHttpApiData a => ByteString -> Either Text a
    parseHeader ByteString
    h)
        NP I xs
    xs <- forall (headers :: [a]) (xs :: [Type]).
    ServantHeaders headers xs =>
    Seq Header -> Maybe (NP I xs)
    forall {k} (headers :: k) (xs :: [Type]).
    ServantHeaders headers xs =>
    Seq Header -> Maybe (NP I xs)
    extractHeaders @headers Seq Header
    headers1
        pure (x -> I x
    forall a. a -> I a
    I x
    x I x -> NP I xs -> NP I (x : xs)
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NP a xs -> NP a (x : xs)
    :* NP I xs
    xs)

    class ServantHeader h (name :: Symbol) x | h -> name x where
      constructHeader :: x -> [HTTP.Header]

    instance
      (KnownSymbol name, ToHttpApiData x) =>
      ServantHeader (Header' mods name x) name x
      where
      constructHeader :: x -> [Header]
    constructHeader x
    x = [(forall (name :: Symbol). KnownSymbol name => HeaderName
    headerName @name, x -> ByteString
    forall a. ToHttpApiData a => a -> ByteString
    toHeader x
    x)]

    instance
      (KnownSymbol name, ToHttpApiData x) =>
      ServantHeader (DescHeader name description x) name x
      where
      constructHeader :: x -> [Header]
    constructHeader x
    x = [(forall (name :: Symbol). KnownSymbol name => HeaderName
    headerName @name, x -> ByteString
    forall a. ToHttpApiData a => a -> ByteString
    toHeader x
    x)]

    instance (ServantHeader h name x) => ServantHeader (OptHeader h) name (Maybe x) where
      constructHeader :: Maybe x -> [Header]
    constructHeader = (x -> [Header]) -> Maybe x -> [Header]
    forall m a. Monoid m => (a -> m) -> Maybe a -> m
    forall (t :: Type -> Type) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap (forall (h :: k) (name :: Symbol) x.
    ServantHeader h name x =>
    x -> [Header]
    forall {k} (h :: k) (name :: Symbol) x.
    ServantHeader h name x =>
    x -> [Header]
    constructHeader @h)

    type instance ResponseType (WithHeaders headers returnType response) = returnType

    type family ResponseTypes (as :: [Type]) where
      ResponseTypes '[] = '[]
      ResponseTypes (a ': as) = ResponseType a ': ResponseTypes as

    -- | 'MultiVerb' produces an endpoint which can return
    -- multiple values with various content types and status codes. It is similar to
    -- 'Servant.API.UVerb.UVerb' and behaves similarly, but it has some important differences:
    --
    --  * Descriptions and statuses can be attached to individual responses without
    --    using wrapper types and without affecting the handler return type.
    --  * The return type of the handler can be decoupled from the types of the
    --    individual responses. One can use a 'Union' type just like for 'Servant.API.UVerb.UVerb',
    --    but 'MultiVerb' also supports using an arbitrary type with an 'AsUnion'
    --    instance. Each response is responsible for their content type.
    --  * Headers can be attached to individual responses, also without affecting
    --    the handler return type.
    --
    -- ==== __Example__
    -- Let us create an endpoint that captures an 'Int' and has the following logic:
    --
    -- * If the number is negative, we return status code 400 and an empty body;
    -- * If the number is even, we return a 'Bool' in the response body;
    -- * If the number is odd, we return another 'Int' in the response body.
    --
    -- >  import qualified Generics.SOP as GSOP
    --
    -- > -- All possible HTTP responses
    -- > type Responses =
    -- >   '[ type RespondEmpty 400 "Negative"
    -- >    , type Respond 200 "Even number" Bool
    -- >    , type Respond 200 "Odd number" Int
    -- >    ]
    -- >
    -- > -- All possible return types
    -- > data Result
    -- >   = NegativeNumber
    -- >   | Odd Int
    -- >   | Even Bool
    -- >   deriving stock (Generic)
    -- >   deriving (AsUnion Responses)
    -- >     via GenericAsUnion Responses Result
    -- >
    -- > instance GSOP.Generic Result
    --
    -- These deriving statements above tie together the responses and the return values, and the order in which they are defined matters. For instance, if @Even@ and @Odd@ had switched places in the definition of @Result@, this would provoke an error:
    --
    --
    -- > • No instance for ‘AsConstructor
    -- >     ((:) @Type Int ('[] @Type)) (Respond 200 "Even number" Bool)’
    -- >         arising from the 'deriving' clause of a data type declaration
    --
    -- If you would prefer to write an intance of 'AsUnion' by yourself, read more in the typeclass' documentation.
    --
    -- Finally, let us write our endpoint description:
    --
    -- > type MultipleChoicesInt =
    -- >   Capture "int" Int
    -- >   :> MultiVerb
    -- >     'GET
    -- >     '[JSON]
    -- >     Responses
    -- >     Result
    data MultiVerb (method :: StdMethod) requestMimeTypes (as :: [Type]) (responses :: Type)

    -- | A 'MultiVerb' endpoint with a single response. Ideal to ensure that there can only be one response.
    type MultiVerb1 method requestMimeTypes a = MultiVerb method requestMimeTypes '[a] (ResponseType a)

    -- | This class is used to convert a handler return type to a union type
    -- including all possible responses of a 'MultiVerb' endpoint.
    --
    -- Any glue code necessary to convert application types to and from the
    -- canonical 'Union' type corresponding to a 'MultiVerb' endpoint should be
    -- packaged into an 'AsUnion' instance.
    --
    -- ==== __Example__
    -- Let us take the example endpoint from the 'MultiVerb' documentation.
    -- There, we derived the 'AsUnion' instance with the help of Generics.
    -- The manual way of implementing the instance is:
    --
    -- > instance AsUnion Responses Result where
    -- >   toUnion NegativeNumber = Z (I ())
    -- >   toUnion (Even b) = S (Z (I b))
    -- >   toUnion (Odd i) = S (S (Z (I i)))
    -- >
    -- >   fromUnion       (Z (I ())) = NegativeNumber
    -- >   fromUnion    (S (Z (I b))) = Even b
    -- >   fromUnion (S (S (Z (I i)))) = Odd i
    -- >   fromUnion (S (S (S x))) = case x of {}
    -- The last 'fromUnion' equation is here to please the pattern checker.
    class AsUnion (as :: [Type]) (r :: Type) where
      toUnion :: r -> Union (ResponseTypes as)
      fromUnion :: Union (ResponseTypes as) -> r

    -- | Unions can be used directly as handler return types using this trivial
    -- instance.
    instance (rs ~ ResponseTypes as) => AsUnion as (Union rs) where
      toUnion :: Union rs -> Union (ResponseTypes as)
    toUnion = Union rs -> Union rs
    Union rs -> Union (ResponseTypes as)
    forall a. a -> a
    id
      fromUnion :: Union (ResponseTypes as) -> Union rs
    fromUnion = Union rs -> Union rs
    Union (ResponseTypes as) -> Union rs
    forall a. a -> a
    id

    -- | A handler with a single response.
    instance (ResponseType r ~ a) => AsUnion '[r] a where
      toUnion :: a -> Union (ResponseTypes '[r])
    toUnion = I a -> NS I '[a]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (I a -> NS I '[a]) -> (a -> I a) -> a -> NS I '[a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> I a
    forall a. a -> I a
    I
      fromUnion :: Union (ResponseTypes '[r]) -> a
    fromUnion = I a -> a
    forall a. I a -> a
    unI (I a -> a) -> (NS I '[a] -> I a) -> NS I '[a] -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NS I '[a] -> I a
    forall {k} (f :: k -> Type) (x :: k). NS f '[x] -> f x
    unZ

    _foo :: Union '[Int]
    _foo :: Union '[Int]
    _foo = forall (as :: [Type]) r.
    AsUnion as r =>
    r -> Union (ResponseTypes as)
    toUnion @'[Respond 200 "test" Int] @Int Int
    3

    class InjectAfter as bs where
      injectAfter :: Union bs -> Union (as .++ bs)

    instance InjectAfter '[] bs where
      injectAfter :: Union bs -> Union ('[] .++ bs)
    injectAfter = Union bs -> Union bs
    Union bs -> Union ('[] .++ bs)
    forall a. a -> a
    id

    instance (InjectAfter as bs) => InjectAfter (a ': as) bs where
      injectAfter :: Union bs -> Union ((a : as) .++ bs)
    injectAfter = NS I (as .++ bs) -> NS I (a : (as .++ bs))
    forall {k} (a :: k -> Type) (xs :: [k]) (x :: k).
    NS a xs -> NS a (x : xs)
    S (NS I (as .++ bs) -> NS I (a : (as .++ bs)))
    -> (Union bs -> NS I (as .++ bs))
    -> Union bs
    -> NS I (a : (as .++ bs))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (as :: [Type]) (bs :: [Type]).
    InjectAfter as bs =>
    Union bs -> Union (as .++ bs)
    injectAfter @as @bs

    class InjectBefore as bs where
      injectBefore :: Union as -> Union (as .++ bs)

    instance InjectBefore '[] bs where
      injectBefore :: Union '[] -> Union ('[] .++ bs)
    injectBefore Union '[]
    x = case Union '[]
    x of {}

    instance (InjectBefore as bs) => InjectBefore (a ': as) bs where
      injectBefore :: Union (a : as) -> Union ((a : as) .++ bs)
    injectBefore (Z I x
    x) = I x -> NS I (x : (as .++ bs))
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z I x
    x
      injectBefore (S NS I xs
    x) = NS I (as .++ bs) -> NS I (a : (as .++ bs))
    forall {k} (a :: k -> Type) (xs :: [k]) (x :: k).
    NS a xs -> NS a (x : xs)
    S (forall (as :: [Type]) (bs :: [Type]).
    InjectBefore as bs =>
    Union as -> Union (as .++ bs)
    injectBefore @as @bs Union as
    NS I xs
    x)

    eitherToUnion ::
      forall as bs a b.
      (InjectAfter as bs, InjectBefore as bs) =>
      (a -> Union as) ->
      (b -> Union bs) ->
      (Either a b -> Union (as .++ bs))
    eitherToUnion :: forall (as :: [Type]) (bs :: [Type]) a b.
    (InjectAfter as bs, InjectBefore as bs) =>
    (a -> Union as)
    -> (b -> Union bs) -> Either a b -> Union (as .++ bs)
    eitherToUnion a -> Union as
    f b -> Union bs
    _ (Left a
    a) = forall (as :: [Type]) (bs :: [Type]).
    InjectBefore as bs =>
    Union as -> Union (as .++ bs)
    injectBefore @as @bs (a -> Union as
    f a
    a)
    eitherToUnion a -> Union as
    _ b -> Union bs
    g (Right b
    b) = forall (as :: [Type]) (bs :: [Type]).
    InjectAfter as bs =>
    Union bs -> Union (as .++ bs)
    injectAfter @as @bs (b -> Union bs
    g b
    b)

    class EitherFromUnion as bs where
      eitherFromUnion ::
        (Union as -> a) ->
        (Union bs -> b) ->
        (Union (as .++ bs) -> Either a b)

    instance EitherFromUnion '[] bs where
      eitherFromUnion :: forall a b.
    (Union '[] -> a)
    -> (Union bs -> b) -> Union ('[] .++ bs) -> Either a b
    eitherFromUnion Union '[] -> a
    _ Union bs -> b
    g = b -> Either a b
    forall a b. b -> Either a b
    Right (b -> Either a b) -> (Union bs -> b) -> Union bs -> Either a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Union bs -> b
    g

    instance (EitherFromUnion as bs) => EitherFromUnion (a ': as) bs where
      eitherFromUnion :: forall a b.
    (Union (a : as) -> a)
    -> (Union bs -> b) -> Union ((a : as) .++ bs) -> Either a b
    eitherFromUnion Union (a : as) -> a
    f Union bs -> b
    _ (Z I x
    x) = a -> Either a b
    forall a b. a -> Either a b
    Left (Union (a : as) -> a
    f (I a -> Union (a : as)
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z I a
    I x
    x))
      eitherFromUnion Union (a : as) -> a
    f Union bs -> b
    g (S NS I xs
    x) = forall (as :: [Type]) (bs :: [Type]) a b.
    EitherFromUnion as bs =>
    (Union as -> a)
    -> (Union bs -> b) -> Union (as .++ bs) -> Either a b
    eitherFromUnion @as @bs (Union (a : as) -> a
    f (Union (a : as) -> a)
    -> (Union as -> Union (a : as)) -> Union as -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Union as -> Union (a : as)
    forall {k} (a :: k -> Type) (xs :: [k]) (x :: k).
    NS a xs -> NS a (x : xs)
    S) Union bs -> b
    g NS I xs
    Union (as .++ bs)
    x

    maybeToUnion ::
      forall as a.
      (InjectAfter as '[()], InjectBefore as '[()]) =>
      (a -> Union as) ->
      (Maybe a -> Union (as .++ '[()]))
    maybeToUnion :: forall (as :: [Type]) a.
    (InjectAfter as '[()], InjectBefore as '[()]) =>
    (a -> Union as) -> Maybe a -> Union (as .++ '[()])
    maybeToUnion a -> Union as
    f (Just a
    a) = forall (as :: [Type]) (bs :: [Type]).
    InjectBefore as bs =>
    Union as -> Union (as .++ bs)
    injectBefore @as @'[()] (a -> Union as
    f a
    a)
    maybeToUnion a -> Union as
    _ Maybe a
    Nothing = forall (as :: [Type]) (bs :: [Type]).
    InjectAfter as bs =>
    Union bs -> Union (as .++ bs)
    injectAfter @as @'[()] (I () -> Union '[()]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (() -> I ()
    forall a. a -> I a
    I ()))

    maybeFromUnion ::
      forall as a.
      (EitherFromUnion as '[()]) =>
      (Union as -> a) ->
      (Union (as .++ '[()]) -> Maybe a)
    maybeFromUnion :: forall (as :: [Type]) a.
    EitherFromUnion as '[()] =>
    (Union as -> a) -> Union (as .++ '[()]) -> Maybe a
    maybeFromUnion Union as -> a
    f =
        Either a (NS I (() : ZonkAny 0)) -> Maybe a
    forall {a} {b}. Either a b -> Maybe a
    leftToMaybe (Either a (NS I (() : ZonkAny 0)) -> Maybe a)
    -> (Union (as .++ '[()]) -> Either a (NS I (() : ZonkAny 0)))
    -> Union (as .++ '[()])
    -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (as :: [Type]) (bs :: [Type]) a b.
    EitherFromUnion as bs =>
    (Union as -> a)
    -> (Union bs -> b) -> Union (as .++ bs) -> Either a b
    eitherFromUnion @as @'[()] Union as -> a
    f (NS I (() : ZonkAny 0) -> Union '[()] -> NS I (() : ZonkAny 0)
    forall a b. a -> b -> a
    const (I () -> NS I (() : ZonkAny 0)
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (() -> I ()
    forall a. a -> I a
    I ())))
        where
            leftToMaybe :: Either a b -> Maybe a
    leftToMaybe = (a -> Maybe a) -> (b -> Maybe a) -> Either a b -> Maybe a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either a -> Maybe a
    forall a. a -> Maybe a
    Just (Maybe a -> b -> Maybe a
    forall a b. a -> b -> a
    const Maybe a
    forall a. Maybe a
    Nothing)

    -- | This class can be instantiated to get automatic derivation of 'AsUnion'
    -- instances via 'GenericAsUnion'. The idea is that one has to make sure that for
    -- each response @r@ in a 'MultiVerb' endpoint, there is an instance of
    -- @AsConstructor xs r@ for some @xs@, and that the list @xss@ of all the
    -- corresponding @xs@ is equal to 'GSOP.Code' of the handler type. Then one can
    -- write:
    -- @
    --   type Responses = ...
    --   data Result = ...
    --     deriving stock (Generic)
    --     deriving (AsUnion Responses) via (GenericAsUnion Responses Result)
    --
    --   instance GSOP.Generic Result
    -- @
    -- and get an 'AsUnion' instance for free.
    --
    -- There are a few predefined instances for constructors taking a single type
    -- corresponding to a simple response, and for empty responses, but in more
    -- general cases one either has to define an 'AsConstructor' instance by hand,
    -- or derive it via 'GenericAsConstructor'.
    class AsConstructor xs r where
      toConstructor :: ResponseType r -> NP I xs
      fromConstructor :: NP I xs -> ResponseType r

    class AsConstructors xss rs where
      toSOP :: Union (ResponseTypes rs) -> SOP I xss
      fromSOP :: SOP I xss -> Union (ResponseTypes rs)

    instance AsConstructors '[] '[] where
      toSOP :: Union (ResponseTypes '[]) -> SOP I '[]
    toSOP Union (ResponseTypes '[])
    x = case Union (ResponseTypes '[])
    x of {}
      fromSOP :: SOP I '[] -> Union (ResponseTypes '[])
    fromSOP SOP I '[]
    x = case SOP I '[]
    x of {}

    instance AsConstructor '[a] (Respond code description a) where
      toConstructor :: ResponseType (Respond code description a) -> NP I '[a]
    toConstructor ResponseType (Respond code description a)
    x = a -> I a
    forall a. a -> I a
    I a
    ResponseType (Respond code description a)
    x I a -> NP I '[] -> NP I '[a]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NP a xs -> NP a (x : xs)
    :* NP I '[]
    forall {k} (a :: k -> Type). NP a '[]
    Nil
      fromConstructor :: NP I '[a] -> ResponseType (Respond code description a)
    fromConstructor = I a -> a
    forall a. I a -> a
    unI (I a -> a) -> (NP I '[a] -> I a) -> NP I '[a] -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NP I '[a] -> I a
    forall {k} (f :: k -> Type) (x :: k) (xs :: [k]).
    NP f (x : xs) -> f x
    hd

    instance AsConstructor '[a] (RespondAs (responseContentTypes :: Type) code description a) where
      toConstructor :: ResponseType (RespondAs responseContentTypes code description a)
    -> NP I '[a]
    toConstructor ResponseType (RespondAs responseContentTypes code description a)
    x = a -> I a
    forall a. a -> I a
    I a
    ResponseType (RespondAs responseContentTypes code description a)
    x I a -> NP I '[] -> NP I '[a]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NP a xs -> NP a (x : xs)
    :* NP I '[]
    forall {k} (a :: k -> Type). NP a '[]
    Nil
      fromConstructor :: NP I '[a]
    -> ResponseType (RespondAs responseContentTypes code description a)
    fromConstructor = I a -> a
    forall a. I a -> a
    unI (I a -> a) -> (NP I '[a] -> I a) -> NP I '[a] -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NP I '[a] -> I a
    forall {k} (f :: k -> Type) (x :: k) (xs :: [k]).
    NP f (x : xs) -> f x
    hd

    instance AsConstructor '[] (RespondEmpty code description) where
      toConstructor :: ResponseType (RespondEmpty code description) -> NP I '[]
    toConstructor ResponseType (RespondEmpty code description)
    _ = NP I '[]
    forall {k} (a :: k -> Type). NP a '[]
    Nil
      fromConstructor :: NP I '[] -> ResponseType (RespondEmpty code description)
    fromConstructor NP I '[]
    _ = ()

    instance AsConstructor '[a] (WithHeaders headers a response) where
      toConstructor :: ResponseType (WithHeaders headers a response) -> NP I '[a]
    toConstructor ResponseType (WithHeaders headers a response)
    a = a -> I a
    forall a. a -> I a
    I a
    ResponseType (WithHeaders headers a response)
    a I a -> NP I '[] -> NP I '[a]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NP a xs -> NP a (x : xs)
    :* NP I '[]
    forall {k} (a :: k -> Type). NP a '[]
    Nil
      fromConstructor :: NP I '[a] -> ResponseType (WithHeaders headers a response)
    fromConstructor (I x
    a :* NP I xs
    Nil) = x
    ResponseType (WithHeaders headers a response)
    a

    newtype GenericAsConstructor r = GenericAsConstructor r

    type instance ResponseType (GenericAsConstructor r) = ResponseType r

    instance
      (GSOP.Code (ResponseType r) ~ '[xs], GSOP.Generic (ResponseType r)) =>
      AsConstructor xs (GenericAsConstructor r)
      where
      toConstructor :: ResponseType (GenericAsConstructor r) -> NP I xs
    toConstructor = NS (NP I) '[xs] -> NP I xs
    forall {k} (f :: k -> Type) (x :: k). NS f '[x] -> f x
    unZ (NS (NP I) '[xs] -> NP I xs)
    -> (ResponseType r -> NS (NP I) '[xs]) -> ResponseType r -> NP I xs
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SOP I '[xs] -> NS (NP I) '[xs]
    forall {k} (f :: k -> Type) (xss :: [[k]]).
    SOP f xss -> NS (NP f) xss
    unSOP (SOP I '[xs] -> NS (NP I) '[xs])
    -> (ResponseType r -> SOP I '[xs])
    -> ResponseType r
    -> NS (NP I) '[xs]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ResponseType r -> SOP I '[xs]
    ResponseType r -> Rep (ResponseType r)
    forall a. Generic a => a -> Rep a
    GSOP.from
      fromConstructor :: NP I xs -> ResponseType (GenericAsConstructor r)
    fromConstructor = SOP I '[xs] -> ResponseType r
    Rep (ResponseType r) -> ResponseType r
    forall a. Generic a => Rep a -> a
    GSOP.to (SOP I '[xs] -> ResponseType r)
    -> (NP I xs -> SOP I '[xs]) -> NP I xs -> ResponseType r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NS (NP I) '[xs] -> SOP I '[xs]
    forall k (f :: k -> Type) (xss :: [[k]]).
    NS (NP f) xss -> SOP f xss
    SOP (NS (NP I) '[xs] -> SOP I '[xs])
    -> (NP I xs -> NS (NP I) '[xs]) -> NP I xs -> SOP I '[xs]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NP I xs -> NS (NP I) '[xs]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z

    instance
      (AsConstructor xs r, AsConstructors xss rs) =>
      AsConstructors (xs ': xss) (r ': rs)
      where
      toSOP :: Union (ResponseTypes (r : rs)) -> SOP I (xs : xss)
    toSOP (Z (I x
    x)) = NS (NP I) (xs : xss) -> SOP I (xs : xss)
    forall k (f :: k -> Type) (xss :: [[k]]).
    NS (NP f) xss -> SOP f xss
    SOP (NS (NP I) (xs : xss) -> SOP I (xs : xss))
    -> (NP I xs -> NS (NP I) (xs : xss)) -> NP I xs -> SOP I (xs : xss)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NP I xs -> NS (NP I) (xs : xss)
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (NP I xs -> SOP I (xs : xss)) -> NP I xs -> SOP I (xs : xss)
    forall a b. (a -> b) -> a -> b
    $ forall (xs :: [Type]) r.
    AsConstructor xs r =>
    ResponseType r -> NP I xs
    toConstructor @xs @r x
    ResponseType r
    x
      toSOP (S NS I xs
    x) = NS (NP I) (xs : xss) -> SOP I (xs : xss)
    forall k (f :: k -> Type) (xss :: [[k]]).
    NS (NP f) xss -> SOP f xss
    SOP (NS (NP I) (xs : xss) -> SOP I (xs : xss))
    -> (SOP I xss -> NS (NP I) (xs : xss))
    -> SOP I xss
    -> SOP I (xs : xss)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NS (NP I) xss -> NS (NP I) (xs : xss)
    forall {k} (a :: k -> Type) (xs :: [k]) (x :: k).
    NS a xs -> NS a (x : xs)
    S (NS (NP I) xss -> NS (NP I) (xs : xss))
    -> (SOP I xss -> NS (NP I) xss)
    -> SOP I xss
    -> NS (NP I) (xs : xss)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SOP I xss -> NS (NP I) xss
    forall {k} (f :: k -> Type) (xss :: [[k]]).
    SOP f xss -> NS (NP f) xss
    unSOP (SOP I xss -> SOP I (xs : xss)) -> SOP I xss -> SOP I (xs : xss)
    forall a b. (a -> b) -> a -> b
    $ forall (xss :: [[Type]]) (rs :: [Type]).
    AsConstructors xss rs =>
    Union (ResponseTypes rs) -> SOP I xss
    toSOP @xss @rs NS I xs
    Union (ResponseTypes rs)
    x

      fromSOP :: SOP I (xs : xss) -> Union (ResponseTypes (r : rs))
    fromSOP (SOP (Z NP I x
    x)) = I (ResponseType r) -> NS I (ResponseType r : ResponseTypes rs)
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (ResponseType r -> I (ResponseType r)
    forall a. a -> I a
    I (forall (xs :: [Type]) r.
    AsConstructor xs r =>
    NP I xs -> ResponseType r
    fromConstructor @xs @r NP I xs
    NP I x
    x))
      fromSOP (SOP (S NS (NP I) xs
    x)) = Union (ResponseTypes rs)
    -> NS I (ResponseType r : ResponseTypes rs)
    forall {k} (a :: k -> Type) (xs :: [k]) (x :: k).
    NS a xs -> NS a (x : xs)
    S (forall (xss :: [[Type]]) (rs :: [Type]).
    AsConstructors xss rs =>
    SOP I xss -> Union (ResponseTypes rs)
    fromSOP @xss @rs (NS (NP I) xss -> SOP I xss
    forall k (f :: k -> Type) (xss :: [[k]]).
    NS (NP f) xss -> SOP f xss
    SOP NS (NP I) xss
    NS (NP I) xs
    x))

    -- | This type is meant to be used with @deriving via@ in order to automatically
    -- generate an 'AsUnion' instance using 'Generics.SOP'.
    --
    -- See 'AsConstructor' for more information and examples.
    newtype GenericAsUnion rs a = GenericAsUnion a

    instance
      (GSOP.Code a ~ xss, GSOP.Generic a, AsConstructors xss rs) =>
      AsUnion rs (GenericAsUnion rs a)
      where
      toUnion :: GenericAsUnion rs a -> Union (ResponseTypes rs)
    toUnion (GenericAsUnion a
    x) = forall (xss :: [[Type]]) (rs :: [Type]).
    AsConstructors xss rs =>
    SOP I xss -> Union (ResponseTypes rs)
    fromSOP @xss @rs (a -> Rep a
    forall a. Generic a => a -> Rep a
    GSOP.from a
    x)
      fromUnion :: Union (ResponseTypes rs) -> GenericAsUnion rs a
    fromUnion = a -> GenericAsUnion rs a
    forall {k} (rs :: k) a. a -> GenericAsUnion rs a
    GenericAsUnion (a -> GenericAsUnion rs a)
    -> (Union (ResponseTypes rs) -> a)
    -> Union (ResponseTypes rs)
    -> GenericAsUnion rs a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SOP I xss -> a
    Rep a -> a
    forall a. Generic a => Rep a -> a
    GSOP.to (SOP I xss -> a)
    -> (Union (ResponseTypes rs) -> SOP I xss)
    -> Union (ResponseTypes rs)
    -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (xss :: [[Type]]) (rs :: [Type]).
    AsConstructors xss rs =>
    Union (ResponseTypes rs) -> SOP I xss
    toSOP @xss @rs

    -- | A handler for a pair of empty responses can be implemented simply by
    -- returning a boolean value. The convention is that the "failure" case, normally
    -- represented by 'False', corresponds to the /first/ response.
    instance
      AsUnion
        '[ RespondEmpty s1 desc1,
           RespondEmpty s2 desc2
         ]
        Bool
      where
      toUnion :: Bool
    -> Union
         (ResponseTypes '[RespondEmpty s1 desc1, RespondEmpty s2 desc2])
    toUnion Bool
    False = I () -> NS I '[(), ()]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (() -> I ()
    forall a. a -> I a
    I ())
      toUnion Bool
    True = Union '[()] -> NS I '[(), ()]
    forall {k} (a :: k -> Type) (xs :: [k]) (x :: k).
    NS a xs -> NS a (x : xs)
    S (I () -> Union '[()]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (() -> I ()
    forall a. a -> I a
    I ()))

      fromUnion :: Union
      (ResponseTypes '[RespondEmpty s1 desc1, RespondEmpty s2 desc2])
    -> Bool
    fromUnion (Z (I ())) = Bool
    False
      fromUnion (S (Z (I ()))) = Bool
    True
      fromUnion (S (S NS I xs
    x)) = case NS I xs
    x of {}

    -- | A handler for a pair of responses where the first is empty can be
    -- implemented simply by returning a 'Maybe' value. The convention is that the
    -- "failure" case, normally represented by 'Nothing', corresponds to the /first/
    -- response.
    instance
      {-# OVERLAPPABLE #-}
      (ResponseType r1 ~ (), ResponseType r2 ~ a) =>
      AsUnion '[r1, r2] (Maybe a)
      where
      toUnion :: Maybe a -> Union (ResponseTypes '[r1, r2])
    toUnion Maybe a
    Nothing = I () -> NS I '[(), a]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (() -> I ()
    forall a. a -> I a
    I ())
      toUnion (Just a
    x) = NS I '[a] -> NS I '[(), a]
    forall {k} (a :: k -> Type) (xs :: [k]) (x :: k).
    NS a xs -> NS a (x : xs)
    S (I a -> NS I '[a]
    forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
    a x -> NS a (x : xs)
    Z (a -> I a
    forall a. a -> I a
    I a
    x))

      fromUnion :: Union (ResponseTypes '[r1, r2]) -> Maybe a
    fromUnion (Z (I ())) = Maybe a
    forall a. Maybe a
    Nothing
      fromUnion (S (Z (I x
    x))) = a -> Maybe a
    forall a. a -> Maybe a
    Just a
    x
    x
      fromUnion (S (S NS I xs
    x)) = case NS I xs
    x of {}