{-# LANGUAGE GADTs #-} {-# LANGUAGE LinearTypes #-} {-# LANGUAGE NoImplicitPrelude #-} -- | This module contains useful functions for working with 'Either's. module Data.Either.Linear ( Either (..) , either , lefts , rights , fromLeft , fromRight , partitionEithers ) where import Data.Unrestricted.Linear import Prelude (Either(..)) -- XXX Design Notes -- Functions like isLeft do not make sense in a linear program. -------------------------------------------------------------------------------- -- | Linearly consume an @Either@ by applying the first linear function on a -- value constructed with @Left@ and the second linear function on a value -- constructed with @Right@. either :: (a %1-> c) -> (b %1-> c) -> Either a b %1-> c either f _ (Left x) = f x either _ g (Right y) = g y -- | Get all the left elements in order, and consume the right ones. lefts :: Consumable b => [Either a b] %1-> [a] lefts [] = [] lefts (Left a : xs) = a : lefts xs lefts (Right b : xs) = lseq b (lefts xs) -- | Get all the right elements in order, and consume the left ones. rights :: Consumable a => [Either a b] %1-> [b] rights [] = [] rights (Left a : xs) = lseq a (rights xs) rights (Right b : xs) = b : rights xs -- | Get the left element of a consumable @Either@ with a default fromLeft :: (Consumable a, Consumable b) => a %1-> Either a b %1-> a fromLeft x (Left a) = lseq x a fromLeft x (Right b) = lseq b x -- | Get the right element of a consumable @Either@ with a default fromRight :: (Consumable a, Consumable b) => b %1-> Either a b %1-> b fromRight x (Left a) = lseq a x fromRight x (Right b) = lseq x b -- | Partition and consume a list of @Either@s into two lists with all the -- lefts in one and the rights in the second, in the order they appeared in the -- initial list. partitionEithers :: [Either a b] %1-> ([a], [b]) partitionEithers [] = ([], []) partitionEithers (x:xs) = fromRecur x (partitionEithers xs) where fromRecur :: Either a b %1-> ([a], [b]) %1-> ([a], [b]) fromRecur (Left a) (as, bs) = (a:as, bs) fromRecur (Right b) (as, bs) = (as, b:bs)