module Agda.Utils.Either
( whileLeft
, caseEitherM
, mapLeft
, mapRight
, traverseEither
, isLeft
, isRight
, fromLeft
, fromRight
, fromLeftM
, fromRightM
, maybeLeft
, maybeRight
, allLeft
, allRight
, groupByEither
, maybeToEither
) where
import Data.Bifunctor
import Data.Either (isLeft, isRight)
import Agda.Utils.List ( listCase )
whileLeft :: Monad m => (a -> Either b c) -> (a -> b -> m a) -> (a -> c -> m d) -> a -> m d
whileLeft :: (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 (a -> m d) -> m a -> m d
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 :: 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 = (a -> m c) -> (b -> m c) -> Either a b -> m c
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> m c
f b -> m c
g (Either a b -> m c) -> m (Either a b) -> m c
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 :: (a -> c) -> Either a b -> Either c b
mapLeft = (a -> c) -> Either a b -> Either c b
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 :: (b -> d) -> Either a b -> Either a d
mapRight = (b -> d) -> Either a b -> Either a d
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 :: (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d)
traverseEither a -> f c
f b -> f d
g = (a -> f (Either c d))
-> (b -> f (Either c d)) -> Either a b -> f (Either c d)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((c -> Either c d) -> f c -> f (Either c d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> Either c d
forall a b. a -> Either a b
Left (f c -> f (Either c d)) -> (a -> f c) -> a -> f (Either c d)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f c
f) ((d -> Either c d) -> f d -> f (Either c d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap d -> Either c d
forall a b. b -> Either a b
Right (f d -> f (Either c d)) -> (b -> f d) -> b -> f (Either c d)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> f d
g)
fromLeft :: (b -> a) -> Either a b -> a
fromLeft :: (b -> a) -> Either a b -> a
fromLeft = (a -> a) -> (b -> a) -> Either a b -> a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> a
forall a. a -> a
id
fromRight :: (a -> b) -> Either a b -> b
fromRight :: (a -> b) -> Either a b -> b
fromRight a -> b
f = (a -> b) -> (b -> b) -> Either a b -> b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> b
f b -> b
forall a. a -> a
id
fromLeftM :: Monad m => (b -> m a) -> m (Either a b) -> m a
fromLeftM :: (b -> m a) -> m (Either a b) -> m a
fromLeftM b -> m a
f m (Either a b)
m = (a -> m a) -> (b -> m a) -> Either a b -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return b -> m a
f (Either a b -> m a) -> m (Either a b) -> m a
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 :: (a -> m b) -> m (Either a b) -> m b
fromRightM a -> m b
f m (Either a b)
m = (a -> m b) -> (b -> m b) -> Either a b -> m b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> m b
f b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return (Either a b -> m b) -> m (Either a b) -> m b
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 :: Either a b -> Maybe a
maybeLeft = (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)
maybeRight :: Either a b -> Maybe b
maybeRight :: Either a b -> Maybe b
maybeRight = (a -> Maybe b) -> (b -> Maybe b) -> Either a b -> Maybe b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe b -> a -> Maybe b
forall a b. a -> b -> a
const Maybe b
forall a. Maybe a
Nothing) b -> Maybe b
forall a. a -> Maybe a
Just
allLeft :: [Either a b] -> Maybe [a]
allLeft :: [Either a b] -> Maybe [a]
allLeft = (Either a b -> Maybe a) -> [Either a b] -> Maybe [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Either a b -> Maybe a
forall a b. Either a b -> Maybe a
maybeLeft
allRight :: [Either a b] -> Maybe [b]
allRight :: [Either a b] -> Maybe [b]
allRight = (Either a b -> Maybe b) -> [Either a b] -> Maybe [b]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Either a b -> Maybe b
forall a b. Either a b -> Maybe b
maybeRight
groupByEither :: forall a b. [Either a b] -> [Either [a] [b]]
groupByEither :: [Either a b] -> [Either [a] [b]]
groupByEither = [Either [a] [b]]
-> (Either a b -> [Either a b] -> [Either [a] [b]])
-> [Either a b]
-> [Either [a] [b]]
forall b a. b -> (a -> [a] -> b) -> [a] -> b
listCase [] (Either [a] [b] -> [Either a b] -> [Either [a] [b]]
go (Either [a] [b] -> [Either a b] -> [Either [a] [b]])
-> (Either a b -> Either [a] [b])
-> Either a b
-> [Either a b]
-> [Either [a] [b]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either a b -> Either [a] [b]
forall a a. Either a a -> Either [a] [a]
init) where
go :: Either [a] [b] -> [Either a b] -> [Either [a] [b]]
go :: Either [a] [b] -> [Either a b] -> [Either [a] [b]]
go Either [a] [b]
acc [] = Either [a] [b] -> Either [a] [b]
forall a a. Either [a] [a] -> Either [a] [a]
adjust Either [a] [b]
acc Either [a] [b] -> [Either [a] [b]] -> [Either [a] [b]]
forall a. a -> [a] -> [a]
: []
go (Left [a]
acc) (Left a
a : [Either a b]
abs) = Either [a] [b] -> [Either a b] -> [Either [a] [b]]
go ([a] -> Either [a] [b]
forall a b. a -> Either a b
Left ([a] -> Either [a] [b]) -> [a] -> Either [a] [b]
forall a b. (a -> b) -> a -> b
$ a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc) [Either a b]
abs
go (Right [b]
acc) (Right b
b : [Either a b]
abs) = Either [a] [b] -> [Either a b] -> [Either [a] [b]]
go ([b] -> Either [a] [b]
forall a b. b -> Either a b
Right ([b] -> Either [a] [b]) -> [b] -> Either [a] [b]
forall a b. (a -> b) -> a -> b
$ b
b b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b]
acc) [Either a b]
abs
go Either [a] [b]
acc (Either a b
ab : [Either a b]
abs) = Either [a] [b] -> Either [a] [b]
forall a a. Either [a] [a] -> Either [a] [a]
adjust Either [a] [b]
acc Either [a] [b] -> [Either [a] [b]] -> [Either [a] [b]]
forall a. a -> [a] -> [a]
: Either [a] [b] -> [Either a b] -> [Either [a] [b]]
go (Either a b -> Either [a] [b]
forall a a. Either a a -> Either [a] [a]
init Either a b
ab) [Either a b]
abs
adjust :: Either [a] [a] -> Either [a] [a]
adjust = ([a] -> [a]) -> ([a] -> [a]) -> Either [a] [a] -> Either [a] [a]
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap [a] -> [a]
forall a. [a] -> [a]
reverse [a] -> [a]
forall a. [a] -> [a]
reverse
init :: Either a a -> Either [a] [a]
init = (a -> [a]) -> (a -> [a]) -> Either a a -> Either [a] [a]
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
maybeToEither :: Maybe a -> Either () a
maybeToEither :: Maybe a -> Either () a
maybeToEither = Either () a -> (a -> Either () a) -> Maybe a -> Either () a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Either () a
forall a b. a -> Either a b
Left ()) a -> Either () a
forall a b. b -> Either a b
Right