/
Except.purs
67 lines (55 loc) · 1.5 KB
/
Except.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
module Run.Except
( Except(..)
, EXCEPT
, FAIL
, _except
, liftExcept
, runExcept
, runFail
, throw
, fail
, catch
) where
import Prelude
import Data.Either (Either(..), either)
import Data.Maybe (Maybe(..))
import Run (Run, SProxy(..), FProxy)
import Run as Run
newtype Except e a = Except e
derive instance functorExcept ∷ Functor (Except e)
type EXCEPT e = FProxy (Except e)
type FAIL = EXCEPT Unit
_except ∷ SProxy "except"
_except = SProxy
liftExcept ∷ ∀ e a r. Except e a → Run (except ∷ EXCEPT e | r) a
liftExcept = Run.liftEffect _except
throw ∷ ∀ e a r. e → Run (except ∷ EXCEPT e | r) a
throw = liftExcept <<< Except
fail ∷ ∀ a r. Run (except ∷ FAIL | r) a
fail = throw unit
catch ∷ ∀ e a r. (e → Run r a) → Run (except ∷ EXCEPT e | r) a → Run r a
catch = loop
where
handle = Run.on _except Left Right
loop k r = case Run.peel r of
Left a → case handle a of
Left (Except e) →
k e
Right a' →
Run.send a' >>= catch k
Right a →
pure a
runExcept ∷ ∀ e a r. Run (except ∷ EXCEPT e | r) a → Run r (Either e a)
runExcept = loop
where
handle = Run.on _except Left Right
loop r = case Run.peel r of
Left a → case handle a of
Left (Except e) →
pure (Left e)
Right a' →
Run.send a' >>= runExcept
Right a →
pure (Right a)
runFail ∷ ∀ a r. Run (except ∷ FAIL | r) a → Run r (Maybe a)
runFail = map (either (const Nothing) Just) <<< runExcept