-
Notifications
You must be signed in to change notification settings - Fork 659
/
Copy pathTask.hs
114 lines (83 loc) · 1.74 KB
/
Task.hs
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
{-# LANGUAGE Rank2Types #-}
module Reporting.Task
( Task
, run
, throw
, mapError
--
, io
, mio
, eio
)
where
-- TASKS
newtype Task x a =
Task
(
forall result. (a -> IO result) -> (x -> IO result) -> IO result
)
run :: Task x a -> IO (Either x a)
run (Task task) =
task (return . Right) (return . Left)
throw :: x -> Task x a
throw x =
Task $ \_ err -> err x
mapError :: (x -> y) -> Task x a -> Task y a
mapError func (Task task) =
Task $ \ok err ->
task ok (err . func)
-- IO
{-# INLINE io #-}
io :: IO a -> Task x a
io work =
Task $ \ok _ -> work >>= ok
mio :: x -> IO (Maybe a) -> Task x a
mio x work =
Task $ \ok err ->
do result <- work
case result of
Just a -> ok a
Nothing -> err x
eio :: (x -> y) -> IO (Either x a) -> Task y a
eio func work =
Task $ \ok err ->
do result <- work
case result of
Right a -> ok a
Left x -> err (func x)
-- INSTANCES
instance Functor (Task x) where
{-# INLINE fmap #-}
fmap func (Task taskA) =
Task $ \ok err ->
let
okA arg = ok (func arg)
in
taskA okA err
instance Applicative (Task x) where
{-# INLINE pure #-}
pure a =
Task $ \ok _ -> ok a
{-# INLINE (<*>) #-}
(<*>) (Task taskFunc) (Task taskArg) =
Task $ \ok err ->
let
okFunc func =
let
okArg arg = ok (func arg)
in
taskArg okArg err
in
taskFunc okFunc err
instance Monad (Task x) where
{-# INLINE return #-}
return = pure
{-# INLINE (>>=) #-}
(>>=) (Task taskA) callback =
Task $ \ok err ->
let
okA a =
case callback a of
Task taskB -> taskB ok err
in
taskA okA err