module Agda.Utils.Either
( whileLeft, caseEitherM
, mapEither, mapLeft, mapRight
, isLeft, isRight
, fromLeft, fromRight
, allRight
, tests
) where
import Control.Applicative
import Agda.Utils.QuickCheck
import Agda.Utils.TestHelpers
whileLeft :: Monad m => (a -> Either b c) -> (a -> b -> m a) -> (a -> c -> m d) -> a -> m d
whileLeft test left right = loop where
loop a =
case test a of
Left b -> loop =<< left a b
Right c -> right a c
caseEitherM :: Monad m => m (Either a b) -> (a -> m c) -> (b -> m c) -> m c
caseEitherM mm f g = either f g =<< mm
mapEither :: (a -> c) -> (b -> d) -> Either a b -> Either c d
mapEither f g = either (Left . f) (Right . g)
mapLeft :: (a -> c) -> Either a b -> Either c b
mapLeft f = mapEither f id
mapRight :: (b -> d) -> Either a b -> Either a d
mapRight = mapEither id
isRight :: Either a b -> Bool
isRight (Right _) = True
isRight (Left _) = False
isLeft :: Either a b -> Bool
isLeft (Right _) = False
isLeft (Left _) = True
fromLeft :: (b -> a) -> Either a b -> a
fromLeft = either id
fromRight :: (a -> b) -> Either a b -> b
fromRight f = either f id
allRight :: [Either a b] -> Maybe [b]
allRight [] = Just []
allRight (Left _ : _ ) = Nothing
allRight (Right b : xs) = (b:) <$> allRight xs
prop_allRight :: Eq b => [Either t b] -> Bool
prop_allRight xs =
allRight xs ==
if all isRight xs then
Just $ map (\ (Right x) -> x) xs
else
Nothing
tests :: IO Bool
tests = runTests "Agda.Utils.Either"
[ quickCheck' (prop_allRight :: [Either Integer Bool] -> Bool)
]