on 63243ca help sign in
elk/libraries/Either.elm
68 lines 1.8 kB history raw
1module Either where
3{-| Represents any data that can take two different types.
5# Type and Constructors
6@docs Either
8# Taking Eithers apart
9@docs either, isLeft, isRight
11# Eithers and Lists
12@docs lefts, rights, partition
14-}
16import List
18{-| Represents any data may take two forms. For example, a user ID may be
19either an `Int` or a `String`.
21This can also be used for error handling `(Either String a)` where
22error messages are stored on the left, and the correct values
23(“right” values) are stored on the right.
24-}
25data Either a b = Left a | Right b
27{-| Apply the first function to a `Left` and the second function to a `Right`.
28This allows the extraction of a value from an `Either`.
29-}
30either : (a -> c) -> (b -> c) -> Either a b -> c
31either f g e = case e of { Left x -> f x ; Right y -> g y }
33{-| True if the value is a `Left`. -}
34isLeft : Either a b -> Bool
35isLeft e = case e of { Left _ -> True ; _ -> False }
37{-| True if the value is a `Right`. -}
38isRight : Either a b -> Bool
39isRight e = case e of { Right _ -> True ; _ -> False }
41{-| Keep only the values held in `Left` values. -}
42lefts : [Either a b] -> [a]
43lefts es = List.foldr consLeft [] es
45{-| Keep only the values held in `Right` values. -}
46rights : [Either a b] -> [b]
47rights es = List.foldr consRight [] es
49{-| Split into two lists, lefts on the left and rights on the right. So we
50have the equivalence: `(partition es == (lefts es, rights es))`
51-}
52partition : [Either a b] -> ([a],[b])
53partition es = List.foldr consEither ([],[]) es
55consLeft e vs =
56 case e of
57 Left v -> v::vs
58 Right _ -> vs
60consRight e vs =
61 case e of
62 Left _ -> vs
63 Right v -> v::vs
65consEither e (ls,rs) =
66 case e of
67 Left l -> (l::ls,rs)
68 Right r -> (ls,r::rs)