never executed always true always false
1 module Reporting.Result where
2
3 import qualified Control.Monad as M
4 import Control.Monad.Except (Except, runExcept)
5 import Data.Coapplicative
6 import qualified Reporting.Annotation as A
7 import qualified Reporting.Region as R
8
9
10 -- TASK
11
12 data Result warning error result =
13 Result
14 [A.Located warning]
15 (RawResult [A.Located error] result)
16 deriving (Show)
17
18
19 data RawResult e a
20 = Ok a
21 | Err e
22 deriving (Show)
23
24
25 -- HELPERS
26
27 ok :: a -> Result w e a
28 ok value =
29 Result [] (Ok value)
30
31
32 throw :: R.Region -> e -> Result w e a
33 throw region err =
34 Result [] (Err [A.A region err])
35
36
37 throwMany :: [A.Located e] -> Result w e a
38 throwMany errors =
39 Result [] (Err errors)
40
41
42 from :: (e -> e') -> Except [A.Located e] a -> Result w e' a
43 from f except =
44 case runExcept except of
45 Right answer ->
46 ok answer
47
48 Left errors ->
49 throwMany (map (fmap f) errors)
50
51
52 mapError :: (e -> e') -> Result w e a -> Result w e' a
53 mapError f (Result warnings rawResult) =
54 Result warnings $
55 case rawResult of
56 Ok v ->
57 Ok v
58
59 Err msgs ->
60 Err (map (fmap f) msgs)
61
62
63 warn :: R.Region -> w -> Result w e ()
64 warn region warning =
65 Result [A.A region warning] (Ok ())
66
67
68 addWarnings :: [A.Located w] -> Result w e a -> Result w e a
69 addWarnings newWarnings (Result warnings rawResult) =
70 Result (newWarnings ++ warnings) rawResult
71
72
73 destruct :: (e -> b) -> (a -> b) -> RawResult e a -> b
74 destruct errFunc okFunc rawResult =
75 case rawResult of
76 Ok answer ->
77 okFunc answer
78
79 Err errors ->
80 errFunc errors
81
82
83 toMaybe :: Result w x a -> Maybe a
84 toMaybe (Result _ (Ok a)) = Just a
85 toMaybe (Result _ (Err _)) = Nothing
86
87
88 toEither :: Result w x a -> Either [x] a
89 toEither (Result _ (Ok a)) = Right a
90 toEither (Result _ (Err x)) = Left $ fmap extract x
91
92
93 -- EXTRA FANCY HELPERS
94
95 instance M.Functor (Result w e) where
96 fmap func (Result warnings rawResult) =
97 case rawResult of
98 Ok a ->
99 Result warnings (Ok (func a))
100
101 Err msgs ->
102 Result warnings (Err msgs)
103
104
105 instance Applicative (Result w e) where
106 pure value =
107 ok value
108
109 (<*>) (Result warnings resultFunc) (Result warnings' resultVal) =
110 Result (warnings ++ warnings') $
111 case (resultFunc, resultVal) of
112 (Ok func, Ok val) ->
113 Ok (func val)
114
115 (Err msgs, Err msgs') ->
116 Err (msgs ++ msgs')
117
118 (Err msgs, _) ->
119 Err msgs
120
121 (_, Err msgs) ->
122 Err msgs
123
124
125 instance M.Monad (Result w e) where
126 return value =
127 ok value
128
129 (>>=) (Result warnings rawResult) callback =
130 case rawResult of
131 Err msg ->
132 Result warnings (Err msg)
133
134 Ok value ->
135 let (Result warnings' rawResult') = callback value
136 in
137 Result (warnings ++ warnings') rawResult'