elm/libraries/Either.elm
evancz d292236b2e Parse out types from ADT constructors.
Should help with type-checking things like the Json library.
2013-05-24 10:47:15 +02:00

52 lines
1.5 KiB
Elm

module Either where
import List
-- Represents any data that can take two different types.
--
-- This can also be used for error handling `(Either String a)` where error
-- messages are stored on the left, and the correct values (“right”
-- values) are stored on the right.
data Either a b = Left a | Right b
-- Apply the first function to a `Left` and the second function to a `Right`.
-- This allows the extraction of a value from an `Either`.
either : (a -> c) -> (b -> c) -> Either a b -> c
either f g e = case e of { Left x -> f x ; Right y -> g y }
-- True if the value is a `Left`.
isLeft : Either a b -> Bool
isLeft e = case e of { Left _ -> True ; _ -> False }
-- True if the value is a `Right`.
isRight : Either a b -> Bool
isRight e = case e of { Right _ -> True ; _ -> False }
-- Keep only the values held in `Left` values.
lefts : [Either a b] -> [a]
lefts es = List.foldr consLeft [] es
-- Keep only the values held in `Right` values.
rights : [Either a b] -> [b]
rights es = List.foldr consRight [] es
-- Split into two lists, lefts on the left and rights on the right. So we
-- have the equivalence: `(partition es == (lefts es, rights es))`
partition : [Either a b] -> ([a],[b])
partition es = List.foldr consEither ([],[]) es
consLeft e vs =
case e of
Left v -> v::vs
Right _ -> vs
consRight e vs =
case e of
Left _ -> vs
Right v -> v::vs
consEither e (ls,rs) =
case e of
Left l -> (l::ls,rs)
Right r -> (ls,r::rs)