packages feed

antelude-0.1.0: src/Antelude/Either.hs

{- |
Module      : Antelude.Either
Description : Contains some functions for Eithers.
Maintainer  : dneavesdev@pm.me
-}
module Antelude.Either
    ( Either (..)
      -- * Rexports
    , Either.either
    , Either.isLeft
    , Either.isRight
      -- * New and Reconstructed for safety
    , filterLefts
    , filterRights
    , fromMaybe
    , fromResult
    , leftWithDefault
    , mapLeft
    , mapRight
    , partition
    , rightWithDefault
    , swap
    ) where

import safe           Antelude.Internal.TypesClasses
    ( Either (..)
    , List
    , Maybe (..)
    , Result (..)
    )

import safe qualified Data.Either                    as Either


-- | Convert a 'Result a b' to an 'Either a b'.
fromResult :: Result err ok -> Either err ok
fromResult = \case
  Err err -> Left err
  Ok ok -> Right ok


-- | Convert a 'Maybe a' to an 'Either () a'.
fromMaybe :: Maybe a -> Either () a
fromMaybe = \case
  Just a -> Right a
  Nothing -> Left ()


-- | Apply a function to the 'Left' case of an 'Either'.
mapLeft :: (left -> newLeft) -> Either left right -> Either newLeft right
mapLeft leftFn (Left left) = Left (leftFn left)
mapLeft _ (Right right)    = Right right


-- | Apply a function to the 'Right' case of an 'Either'.
mapRight :: (right -> newRight) -> Either left right -> Either left newRight
mapRight rightFn (Right right) = Right (rightFn right)
mapRight _ (Left left)         = Left left


-- | Swap the 'Left'/'Right' in an 'Either'
swap :: Either left right -> Either right left
swap (Left a)  = Right a
swap (Right a) = Left a


-- | Get the 'Left' case of an 'Either', or a default if the 'Either' is 'Right'.
leftWithDefault :: a -> Either a b -> a
leftWithDefault dflt = \case
  Left a -> a
  Right _ -> dflt


-- | Get the 'Right' case of an 'Either', or a default if the 'Either' is 'Left'.
rightWithDefault :: b -> Either a b -> b
rightWithDefault dflt = \case
  Left _ -> dflt
  Right b -> b


-- | Take a 'List' of 'Either left right' and create a Tuple with 'List left' and 'List right'.
partition :: List (Either left right) -> (List left, List right)
partition = Either.partitionEithers


-- | Take a 'List' of 'Either a b' and return a 'List' containing all of the values from the 'Left' cases.
filterLefts :: List (Either left right) -> List left
filterLefts = Either.lefts


-- | Take a 'List' of 'Either a b' and return a 'List' containing all of the values from the 'Right' cases.
filterRights :: List (Either left right) -> List right
filterRights = Either.rights