0 | module Idrall.IOEither
 1 |
 2 | public export
 3 | data IOEither a b
 4 |  = MkIOEither (IO (Either a b))
 5 |
 6 | export
 7 | Functor (IOEither a) where
 8 |   map func (MkIOEither x) = MkIOEither (map (map func) x)
 9 |
10 | ||| Lift a two-argument function to an applicative
11 | export
12 | liftA2 : Applicative f => (a -> b -> c) -> f a -> f b -> f c
13 | liftA2 f a b = (map f a) <*> b
14 |
15 | export
16 | Applicative (IOEither a) where
17 |   pure x = MkIOEither (pure (pure x))
18 |   (<*>) (MkIOEither x) (MkIOEither y) = MkIOEither (liftA2 (<*>) x y)
19 |
20 | export
21 | Monad (IOEither a) where
22 |   (>>=) (MkIOEither x) f = MkIOEither (do x' <- x
23 |                                           (case x' of
24 |                                                 (Left l) => pure (Left l)
25 |                                                 (Right r) => let MkIOEither g = f r in
26 |                                                                  g))
27 |   join x = x >>= id
28 |
29 | export
30 | liftEither : Either e a -> IOEither e a
31 | liftEither = MkIOEither . pure
32 |
33 | export
34 | liftIOEither : IOEither e a -> IO (Either e a)
35 | liftIOEither (MkIOEither x) = x
36 |
37 | export
38 | mapErr : (e -> e') -> IOEither e a -> IOEither e' a
39 | mapErr f (MkIOEither x) = MkIOEither (do
40 |   x' <- x
41 |   case x' of
42 |         (Left l) => pure (Left (f l))
43 |         (Right r) => pure (Right r))
44 |
45 |