module Data.Either.Strict (
Either(Left, Right)
, isRight
, isLeft
, either
, lefts
, rights
, partitionEithers
, _Left
, _Right
) where
import Data.Strict.Either (Either (Left, Right), either, isLeft,
isRight)
import Prelude hiding (Either (..), either)
import qualified Prelude as L
import Control.DeepSeq (NFData (..))
import Control.Lens.Iso (Strict (..), Swapped (..), iso)
import Control.Lens.Prism (Prism, prism)
import Data.Aeson (FromJSON (..), ToJSON (..))
import Data.Bifoldable (Bifoldable (..))
import Data.Bifunctor (Bifunctor (..))
import Data.Binary (Binary (..))
import Data.Bitraversable (Bitraversable (..))
#if MIN_VERSION_base(4,7,0)
import Data.Data (Data (..), Typeable)
#else
import Data.Data (Data (..), Typeable2 (..))
#endif
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative (pure, (<$>))
import Data.Foldable (Foldable (..))
import Data.Traversable (Traversable (..))
import Data.Monoid (Monoid (..))
#endif
#if __GLASGOW_HASKELL__ >= 706
import GHC.Generics (Generic (..))
#endif
import Test.QuickCheck (Arbitrary (..))
import Data.Hashable (Hashable(..))
toStrict :: L.Either a b -> Either a b
toStrict (L.Left x) = Left x
toStrict (L.Right y) = Right y
toLazy :: Either a b -> L.Either a b
toLazy (Left x) = L.Left x
toLazy (Right y) = L.Right y
deriving instance (Data a, Data b) => Data (Either a b)
#if MIN_VERSION_base(4,7,0)
deriving instance Typeable Either
#else
deriving instance Typeable2 Either
#endif
#if __GLASGOW_HASKELL__ >= 706
deriving instance Generic (Either a b)
#endif
instance Foldable (Either e) where
foldr _ y (Left _) = y
foldr f y (Right x) = f x y
foldl _ y (Left _) = y
foldl f y (Right x) = f y x
instance Traversable (Either e) where
traverse _ (Left x) = pure (Left x)
traverse f (Right x) = Right <$> f x
instance (NFData a, NFData b) => NFData (Either a b) where
rnf = rnf . toLazy
instance (Binary a, Binary b) => Binary (Either a b) where
put = put . toLazy
get = toStrict <$> get
instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
toJSON = toJSON . toLazy
instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
parseJSON val = toStrict <$> parseJSON val
instance (Arbitrary a, Arbitrary b) => Arbitrary (Either a b) where
arbitrary = toStrict <$> arbitrary
shrink = map toStrict . shrink . toLazy
instance Bifunctor Either where
bimap f _ (Left a) = Left (f a)
bimap _ g (Right a) = Right (g a)
first f = either (Left . f) Right
second g = either Left (Right . g)
instance Bifoldable Either where
bifold (Left a) = a
bifold (Right b) = b
bifoldMap = either
bifoldr f _ c (Left a) = f a c
bifoldr _ g c (Right b) = g b c
bifoldl f _ c (Left a) = f c a
bifoldl _ g c (Right b) = g c b
instance Bitraversable Either where
bitraverse f _ (Left a) = fmap Left (f a)
bitraverse _ g (Right b) = fmap Right (g b)
#if !MIN_VERSION_bifunctors(5,1,0)
bisequenceA = either (fmap Left) (fmap Right)
#endif
instance Strict (L.Either a b) (Either a b) where
strict = iso toStrict toLazy
instance Swapped Either where
swapped = either Right Left `iso` either Right Left
instance (Hashable a, Hashable b) => Hashable (Either a b) where
hashWithSalt salt = hashWithSalt salt . toLazy
lefts :: [Either a b] -> [a]
lefts x = [a | Left a <- x]
rights :: [Either a b] -> [b]
rights x = [a | Right a <- x]
partitionEithers :: [Either a b] -> ([a],[b])
partitionEithers =
Prelude.foldr (either left right) ([],[])
where
left a ~(l, r) = (a:l, r)
right a ~(l, r) = (l, a:r)
_Left :: Prism (Either a c) (Either b c) a b
_Left = prism Left $ either L.Right (L.Left . Right)
_Right :: Prism (Either c a) (Either c b) a b
_Right = prism Right $ either (L.Left . Left) L.Right