    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.Strict.Either
    -- Copyright   :  (c) 2006-2007 Roman Leshchinskiy
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Roman Leshchinskiy <rl@cse.unsw.edu.au>
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- Strict @Either@.
    --
    -- Same as the standard Haskell @Either@, but @Left _|_ = Right _|_ = _|_@
    --
    -----------------------------------------------------------------------------

    module Data.Strict.Either (
        Either(..)
      , either
      , isLeft, isRight
      , fromLeft, fromRight
    ) where

    import Prelude hiding( Either(..), either )

    -- | The strict choice type.
    data Either a b = Left !a | Right !b deriving(Either a b -> Either a b -> Bool
    (Either a b -> Either a b -> Bool)
    -> (Either a b -> Either a b -> Bool) -> Eq (Either a b)
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    forall a b. (Eq a, Eq b) => Either a b -> Either a b -> Bool
    /= :: Either a b -> Either a b -> Bool
    $c/= :: forall a b. (Eq a, Eq b) => Either a b -> Either a b -> Bool
    == :: Either a b -> Either a b -> Bool
    $c== :: forall a b. (Eq a, Eq b) => Either a b -> Either a b -> Bool
    Eq, Eq (Either a b)
    Eq (Either a b) =>
    (Either a b -> Either a b -> Ordering)
    -> (Either a b -> Either a b -> Bool)
    -> (Either a b -> Either a b -> Bool)
    -> (Either a b -> Either a b -> Bool)
    -> (Either a b -> Either a b -> Bool)
    -> (Either a b -> Either a b -> Either a b)
    -> (Either a b -> Either a b -> Either a b)
    -> Ord (Either a b)
    Either a b -> Either a b -> Bool
    Either a b -> Either a b -> Ordering
    Either a b -> Either a b -> Either a b
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall a b. (Ord a, Ord b) => Eq (Either a b)
    forall a b. (Ord a, Ord b) => Either a b -> Either a b -> Bool
    forall a b. (Ord a, Ord b) => Either a b -> Either a b -> Ordering
    forall a b.
    (Ord a, Ord b) =>
    Either a b -> Either a b -> Either a b
    min :: Either a b -> Either a b -> Either a b
    $cmin :: forall a b.
    (Ord a, Ord b) =>
    Either a b -> Either a b -> Either a b
    max :: Either a b -> Either a b -> Either a b
    $cmax :: forall a b.
    (Ord a, Ord b) =>
    Either a b -> Either a b -> Either a b
    >= :: Either a b -> Either a b -> Bool
    $c>= :: forall a b. (Ord a, Ord b) => Either a b -> Either a b -> Bool
    > :: Either a b -> Either a b -> Bool
    $c> :: forall a b. (Ord a, Ord b) => Either a b -> Either a b -> Bool
    <= :: Either a b -> Either a b -> Bool
    $c<= :: forall a b. (Ord a, Ord b) => Either a b -> Either a b -> Bool
    < :: Either a b -> Either a b -> Bool
    $c< :: forall a b. (Ord a, Ord b) => Either a b -> Either a b -> Bool
    compare :: Either a b -> Either a b -> Ordering
    $ccompare :: forall a b. (Ord a, Ord b) => Either a b -> Either a b -> Ordering
    $cp1Ord :: forall a b. (Ord a, Ord b) => Eq (Either a b)
    Ord, ReadPrec [Either a b]
    ReadPrec (Either a b)
    Int -> ReadS (Either a b)
    ReadS [Either a b]
    (Int -> ReadS (Either a b))
    -> ReadS [Either a b]
    -> ReadPrec (Either a b)
    -> ReadPrec [Either a b]
    -> Read (Either a b)
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    forall a b. (Read a, Read b) => ReadPrec [Either a b]
    forall a b. (Read a, Read b) => ReadPrec (Either a b)
    forall a b. (Read a, Read b) => Int -> ReadS (Either a b)
    forall a b. (Read a, Read b) => ReadS [Either a b]
    readListPrec :: ReadPrec [Either a b]
    $creadListPrec :: forall a b. (Read a, Read b) => ReadPrec [Either a b]
    readPrec :: ReadPrec (Either a b)
    $creadPrec :: forall a b. (Read a, Read b) => ReadPrec (Either a b)
    readList :: ReadS [Either a b]
    $creadList :: forall a b. (Read a, Read b) => ReadS [Either a b]
    readsPrec :: Int -> ReadS (Either a b)
    $creadsPrec :: forall a b. (Read a, Read b) => Int -> ReadS (Either a b)
    Read, Int -> Either a b -> ShowS
    [Either a b] -> ShowS
    Either a b -> String
    (Int -> Either a b -> ShowS)
    -> (Either a b -> String)
    -> ([Either a b] -> ShowS)
    -> Show (Either a b)
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    forall a b. (Show a, Show b) => Int -> Either a b -> ShowS
    forall a b. (Show a, Show b) => [Either a b] -> ShowS
    forall a b. (Show a, Show b) => Either a b -> String
    showList :: [Either a b] -> ShowS
    $cshowList :: forall a b. (Show a, Show b) => [Either a b] -> ShowS
    show :: Either a b -> String
    $cshow :: forall a b. (Show a, Show b) => Either a b -> String
    showsPrec :: Int -> Either a b -> ShowS
    $cshowsPrec :: forall a b. (Show a, Show b) => Int -> Either a b -> ShowS
    Show)

    instance Functor (Either a) where
      fmap :: (a -> b) -> Either a a -> Either a b
    fmap _ (Left  x :: a
    x) = a -> Either a b
    forall a b. a -> Either a b
    Left a
    x
      fmap f :: a -> b
    f (Right y :: a
    y) = b -> Either a b
    forall a b. b -> Either a b
    Right (a -> b
    f a
    y)

    -- | Case analysis: if the value is @'Left' a@, apply the first function to @a@;
    -- if it is @'Right' b@, apply the second function to @b@.
    either :: (a -> c) -> (b -> c) -> Either a b -> c
    either :: (a -> c) -> (b -> c) -> Either a b -> c
    either f :: a -> c
    f _ (Left  x :: a
    x) = a -> c
    f a
    x
    either _ g :: b -> c
    g (Right y :: b
    y) = b -> c
    g b
    y

    -- | Yields 'True' iff the argument is of the form @Left _@.
    --
    isLeft :: Either a b -> Bool
    isLeft :: Either a b -> Bool
    isLeft (Left _) = Bool
    True
    isLeft _        = Bool
    False

    -- | Yields 'True' iff the argument is of the form @Right _@.
    --
    isRight :: Either a b -> Bool
    isRight :: Either a b -> Bool
    isRight (Right _) = Bool
    True
    isRight _         = Bool
    False

    -- | Extracts the element out of a 'Left' and throws an error if the argument
    -- is a 'Right'.
    fromLeft :: Either a b -> a
    fromLeft :: Either a b -> a
    fromLeft (Left x :: a
    x) = a
    x
    fromLeft _        = String -> a
    forall a. HasCallStack => String -> a
    error "Data.Strict.Either.fromLeft: Right"

    -- | Extracts the element out of a 'Right' and throws an error if the argument
    -- is a 'Left'.
    fromRight :: Either a b -> b
    fromRight :: Either a b -> b
    fromRight (Right x :: b
    x) = b
    x
    fromRight _         = String -> b
    forall a. HasCallStack => String -> a
    error "Data.Strict.Either.fromRight: Left"