{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Data.List.EitherFunctions
( partlyMap
, groupEither
, spanLeft
, spanRight
) where
import Data.Either (Either (..))
import Data.List (map)
import Data.Maybe (Maybe (..), maybe)
{- |
>>> import Prelude (even, show)
>>> partlyMap (\x -> if even x then Just (show x) else Nothing) [1..5]
[Left 1,Right "2",Left 3,Right "4",Left 5]
-}
partlyMap :: (a -> Maybe b) -> [a] -> [Either a b]
partlyMap f = map (\x -> maybe (Left x) Right (f x))
{- |
>>> groupEither [Left 1, Left 2, Right 'a', Left 3, Right 'b', Right 'c']
[Left [1,2],Right "a",Left [3],Right "bc"]
-}
groupEither :: [Either a b] -> [Either [a] [b]]
groupEither [] = []
groupEither ((Left x) : xs) = let (ys, zs) = spanLeft xs
in Left (x : ys) : groupEither zs
groupEither ((Right x) : xs) = let (ys, zs) = spanRight xs
in Right (x : ys) : groupEither zs
{- |
>>> spanLeft [Left 1, Left 2, Right 'a', Left 3, Right 'b', Right 'c']
([1,2],[Right 'a',Left 3,Right 'b',Right 'c'])
>>> spanLeft [Right 'a', Left 3, Right 'b', Right 'c']
([],[Right 'a',Left 3,Right 'b',Right 'c'])
-}
spanLeft :: [Either a b] -> ([a], [Either a b])
spanLeft [] = ([], [])
spanLeft ((Left x) : xs) = let (ys, zs) = spanLeft xs
in (x : ys, zs)
spanLeft xs = ([], xs)
{- |
>>> spanRight [Left 1, Left 2, Right 'a', Left 3, Right 'b', Right 'c']
("",[Left 1,Left 2,Right 'a',Left 3,Right 'b',Right 'c'])
>>> spanRight [Right 'a', Left 3, Right 'b', Right 'c']
("a",[Left 3,Right 'b',Right 'c'])
-}
spanRight :: [Either a b] -> ([b], [Either a b])
spanRight [] = ([], [])
spanRight ((Right x) : xs) = let (ys, zs) = spanRight xs
in (x : ys, zs)
spanRight xs = ([], xs)