module Agda.Utils.Either
( whileLeft
, caseEitherM
, mapLeft
, mapRight
, traverseEither
, isLeft
, isRight
, fromLeft
, fromRight
, fromLeftM
, fromRightM
, maybeLeft
, maybeRight
, allLeft
, allRight
, groupByEither
, maybeToEither
, swapEither
) where
import Data.Bifunctor
import Data.Either (isLeft, isRight)
import Data.List (unfoldr)
import Agda.Utils.List ( spanJust )
import Agda.Utils.List1 ( List1, pattern (:|), (<|) )
import qualified Agda.Utils.List1 as List1
import Agda.Utils.Singleton
whileLeft :: Monad m => (a -> Either b c) -> (a -> b -> m a) -> (a -> c -> m d) -> a -> m d
whileLeft :: forall (m :: * -> *) a b c d.
Monad m =>
(a -> Either b c) -> (a -> b -> m a) -> (a -> c -> m d) -> a -> m d
whileLeft a -> Either b c
test a -> b -> m a
left a -> c -> m d
right = a -> m d
loop where
loop :: a -> m d
loop a
a =
case a -> Either b c
test a
a of
Left b
b -> a -> m d
loop forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> b -> m a
left a
a b
b
Right c
c -> a -> c -> m d
right a
a c
c
caseEitherM :: Monad m => m (Either a b) -> (a -> m c) -> (b -> m c) -> m c
caseEitherM :: forall (m :: * -> *) a b c.
Monad m =>
m (Either a b) -> (a -> m c) -> (b -> m c) -> m c
caseEitherM m (Either a b)
mm a -> m c
f b -> m c
g = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> m c
f b -> m c
g forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m (Either a b)
mm
mapLeft :: (a -> c) -> Either a b -> Either c b
mapLeft :: forall a c b. (a -> c) -> Either a b -> Either c b
mapLeft = forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first
mapRight :: (b -> d) -> Either a b -> Either a d
mapRight :: forall b d a. (b -> d) -> Either a b -> Either a d
mapRight = forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second
traverseEither :: Functor f => (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d)
traverseEither :: forall (f :: * -> *) a c b d.
Functor f =>
(a -> f c) -> (b -> f d) -> Either a b -> f (Either c d)
traverseEither a -> f c
f b -> f d
g = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f c
f) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> f d
g)
fromLeft :: (b -> a) -> Either a b -> a
fromLeft :: forall b a. (b -> a) -> Either a b -> a
fromLeft = (forall a. a -> a
id forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
`either`)
fromRight :: (a -> b) -> Either a b -> b
fromRight :: forall a b. (a -> b) -> Either a b -> b
fromRight = (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
`either` forall a. a -> a
id)
fromLeftM :: Monad m => (b -> m a) -> m (Either a b) -> m a
fromLeftM :: forall (m :: * -> *) b a.
Monad m =>
(b -> m a) -> m (Either a b) -> m a
fromLeftM b -> m a
f m (Either a b)
m = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall (m :: * -> *) a. Monad m => a -> m a
return b -> m a
f forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m (Either a b)
m
fromRightM :: Monad m => (a -> m b) -> m (Either a b) -> m b
fromRightM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> m (Either a b) -> m b
fromRightM a -> m b
f m (Either a b)
m = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> m b
f forall (m :: * -> *) a. Monad m => a -> m a
return forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m (Either a b)
m
maybeLeft :: Either a b -> Maybe a
maybeLeft :: forall a b. Either a b -> Maybe a
maybeLeft = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> Maybe a
Just (forall a b. a -> b -> a
const forall a. Maybe a
Nothing)
maybeRight :: Either a b -> Maybe b
maybeRight :: forall a b. Either a b -> Maybe b
maybeRight = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) forall a. a -> Maybe a
Just
allLeft :: [Either a b] -> Maybe [a]
allLeft :: forall a b. [Either a b] -> Maybe [a]
allLeft = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a b. Either a b -> Maybe a
maybeLeft
allRight :: [Either a b] -> Maybe [b]
allRight :: forall a b. [Either a b] -> Maybe [b]
allRight = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a b. Either a b -> Maybe b
maybeRight
groupByEither :: forall a b. [Either a b] -> [Either (List1 a) (List1 b)]
groupByEither :: forall a b. [Either a b] -> [Either (List1 a) (List1 b)]
groupByEither = forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr [Either a b] -> Maybe (Either (List1 a) (List1 b), [Either a b])
c
where
c :: [Either a b] -> Maybe (Either (List1 a) (List1 b), [Either a b])
c :: [Either a b] -> Maybe (Either (List1 a) (List1 b), [Either a b])
c [] = forall a. Maybe a
Nothing
c (Left a
a : [Either a b]
xs) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
a forall a. a -> [a] -> NonEmpty a
:|)) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> Maybe b) -> [a] -> (Prefix b, [a])
spanJust forall a b. Either a b -> Maybe a
maybeLeft [Either a b]
xs
c (Right b
b : [Either a b]
xs) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b
b forall a. a -> [a] -> NonEmpty a
:|)) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> Maybe b) -> [a] -> (Prefix b, [a])
spanJust forall a b. Either a b -> Maybe b
maybeRight [Either a b]
xs
maybeToEither :: e -> Maybe a -> Either e a
maybeToEither :: forall e a. e -> Maybe a -> Either e a
maybeToEither e
e = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. a -> Either a b
Left e
e) forall a b. b -> Either a b
Right
swapEither :: Either a b -> Either b a
swapEither :: forall a b. Either a b -> Either b a
swapEither = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. b -> Either a b
Right forall a b. a -> Either a b
Left