diff options
Diffstat (limited to 'app/Data/Res.hs')
-rw-r--r-- | app/Data/Res.hs | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/app/Data/Res.hs b/app/Data/Res.hs new file mode 100644 index 0000000..e8c4ca4 --- /dev/null +++ b/app/Data/Res.hs | |||
@@ -0,0 +1,31 @@ | |||
1 | module Data.Res where | ||
2 | |||
3 | import Control.Applicative | ||
4 | import Data.String (IsString (fromString)) | ||
5 | |||
6 | data Res e r = Ok r | Err e | ||
7 | |||
8 | instance Functor (Res e) where | ||
9 | fmap f (Ok v) = Ok (f v) | ||
10 | fmap _ (Err e) = Err e | ||
11 | |||
12 | instance Applicative (Res e) where | ||
13 | pure = Ok | ||
14 | (Ok f) <*> (Ok v) = Ok (f v) | ||
15 | (Err e) <*> _ = Err e | ||
16 | _ <*> (Err e) = Err e | ||
17 | |||
18 | instance Monad (Res e) where | ||
19 | (Ok v) >>= f = f v | ||
20 | (Err e) >>= _ = Err e | ||
21 | |||
22 | instance IsString e => MonadFail (Res e) where | ||
23 | fail = Err . fromString | ||
24 | |||
25 | instance IsString e => Alternative (Res e) where | ||
26 | empty = fail "mzero" | ||
27 | m1@(Ok _) <|> _ = m1 | ||
28 | (Err _) <|> m2 = m2 | ||
29 | |||
30 | liftEither :: Either e r -> Res e r | ||
31 | liftEither = either Err Ok | ||