content: {-# LANGUAGE CPP, ConstraintKinds #-}
  {-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
  
  -- | This module extends "Data.Either" with extra operations, particularly
  --   to quickly extract from inside an 'Either'. Some of these operations are
  --   partial, and should be used with care in production-quality code.
  --
  --   If you need more 'Either' functions see the
  --   <https://hackage.haskell.org/package/either either>.
  module Data.Either.Extra(
      module Data.Either,
      fromLeft, fromRight, fromEither,
      fromLeft', fromRight',
      eitherToMaybe, maybeToEither,
      mapLeft, mapRight,
      ) where
  
  import Data.Either
  import Partial
  
  
  #if __GLASGOW_HASKELL__ < 801
  
  -- | Return the contents of a 'Left'-value or a default value otherwise.
  --
  -- > fromLeft 1 (Left 3) == 3
  -- > fromLeft 1 (Right "foo") == 1
  fromLeft :: a -> Either a b -> a
  fromLeft _ (Left a) = a
  fromLeft a _        = a
  
  -- | Return the contents of a 'Right'-value or a default value otherwise.
  --
  -- > fromRight 1 (Right 3) == 3
  -- > fromRight 1 (Left "foo") == 1
  fromRight :: b -> Either a b -> b
  fromRight _ (Right b) = b
  fromRight b _         = b
  
  #endif
  
  
  -- | The 'fromLeft'' function extracts the element out of a 'Left' and
  --   throws an error if its argument is 'Right'.
  --   Much like 'fromJust', using this function in polished code is usually a bad idea.
  --
  -- > \x -> fromLeft' (Left  x) == x
  -- > \x -> fromLeft' (Right x) == undefined
  fromLeft' :: Partial => Either l r -> l
  fromLeft' (Left x) = x
  fromLeft' _ = error "fromLeft', given a Right"
  
  -- | The 'fromRight'' function extracts the element out of a 'Right' and
  --   throws an error if its argument is 'Left'.
  --   Much like 'fromJust', using this function in polished code is usually a bad idea.
  --
  -- > \x -> fromRight' (Right x) == x
  -- > \x -> fromRight' (Left  x) == undefined
  fromRight' :: Partial => Either l r -> r
  fromRight' (Right x) = x
  fromRight' _ = error "fromRight', given a Left"
  
  
  -- | Pull the value out of an 'Either' where both alternatives
  --   have the same type.
  --
  -- > \x -> fromEither (Left x ) == x
  -- > \x -> fromEither (Right x) == x
  fromEither :: Either a a -> a
  fromEither = either id id
  
  
  -- | Given a 'Maybe', convert it to an 'Either', providing a suitable
  --   value for the 'Left' should the value be 'Nothing'.
  --
  -- > \a b -> maybeToEither a (Just b) == Right b
  -- > \a -> maybeToEither a Nothing == Left a
  maybeToEither :: a -> Maybe b -> Either a b
  maybeToEither a (Just b) = Right b
  maybeToEither a Nothing = Left a
  
  -- | Given an 'Either', convert it to a 'Maybe', where 'Left' becomes 'Nothing'.
  --
  -- > \x -> eitherToMaybe (Left x) == Nothing
  -- > \x -> eitherToMaybe (Right x) == Just x
  eitherToMaybe :: Either a b -> Maybe b
  eitherToMaybe = either (const Nothing) Just
  
  
  -- | The 'mapLeft' function takes a function and applies it to an Either value
  -- iff the value takes the form @'Left' _@.
  --
  -- > mapLeft show (Left 1) == Left "1"
  -- > mapLeft show (Right True) == Right True
  mapLeft :: (a -> c) -> Either a b -> Either c b
  mapLeft f = either (Left . f) Right
  
  -- | The 'mapRight' function takes a function and applies it to an Either value
  -- iff the value takes the form @'Right' _@.
  --
  -- > mapRight show (Left 1) == Left 1
  -- > mapRight show (Right True) == Right "True"
  mapRight :: (b -> c) -> Either a b -> Either a c
  mapRight = fmap
  