on 577fc17 help sign in
elk/libraries/Either.elm
91 lines 2.3 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
17import List ((::))
19{-| Represents any data may take two forms. For example, a user ID may be
20either an `Int` or a `String`.
22This can also be used for error handling `(Either String a)` where
23error messages are stored on the left, and the correct values
24(“right” values) are stored on the right.
25-}
26data Either a b = Left a | Right b
28{-| Apply the first function to a `Left` and the second function to a `Right`.
29This allows the extraction of a value from an `Either`.
31 either (\n -> n + 1) sqrt (Left 4) == 5
32 either (\n -> n + 1) sqrt (Right 4) == 2
34 map : (a -> b) -> Either err a -> Either err b
35 map f e = either Left (\x -> Right (f x)) e
36-}
37either : (a -> c) -> (b -> c) -> Either a b -> c
38either f g e = case e of { Left x -> f x ; Right y -> g y }
40{-| True if the value is a `Left`.
42 isLeft (Left "Cat") == True
43 isLeft (Right 1123) == False
44-}
45isLeft : Either a b -> Bool
46isLeft e = case e of { Left _ -> True ; _ -> False }
48{-| True if the value is a `Right`.
50 isRight (Left "Cat") == False
51 isRight (Right 1123) == True
52-}
53isRight : Either a b -> Bool
54isRight e = case e of { Right _ -> True ; _ -> False }
56{-| Keep only the values held in `Left` values.
58 lefts [Left 3, Right 'a', Left 5, Right "eight"] == [3,5]
59-}
60lefts : [Either a b] -> [a]
61lefts es = List.foldr consLeft [] es
63{-| Keep only the values held in `Right` values.
65 rights [Left 3, Right 'a', Left 5, Right 'b'] == ['a','b']
66-}
67rights : [Either a b] -> [b]
68rights es = List.foldr consRight [] es
70{-| Split into two lists, lefts on the left and rights on the right. So we
71have the equivalence: `(partition es == (lefts es, rights es))`
73 partition [Left 3, Right 'a', Left 5, Right 'b'] == ([3,5],['a','b'])
74-}
75partition : [Either a b] -> ([a],[b])
76partition es = List.foldr consEither ([],[]) es
78consLeft e vs =
79 case e of
80 Left v -> v::vs
81 Right _ -> vs
83consRight e vs =
84 case e of
85 Left _ -> vs
86 Right v -> v::vs
88consEither e (ls,rs) =
89 case e of
90 Left l -> (l::ls,rs)
91 Right r -> (ls,r::rs)