----------------------------------------------------------------------------- -- | -- Module : Data.Result -- Copyright : (c) 2020-2021 EMQ Technologies Co., Ltd. -- License : BSD-style (see the LICENSE file) -- -- Maintainer : Feng Lee, feng@emqx.io -- Yang M, yangm@emqx.io -- Stability : experimental -- Portability : portable -- -- The Result datatype. -- ----------------------------------------------------------------------------- module Data.Result ( Result(..) , isOk , isError , fromOk , fromError ) where import Control.Monad (class Applicative, class Monad, pure, liftA1) import Data.Monoid (mempty) import Data.Functor (class Functor, map) import Data.Function (error) import Data.List ((++)) import Data.Show (class Show, show) import Data.Read (class Read, read) import Data.Eq (class Eq, eq) import Data.Ord (class Ord, compare) import Data.Ordering (Ordering(..)) import Data.Semigroup (class Semigroup) import Data.Foldable (class Foldable) import Data.Traversable (class Traversable) data Result e a = Ok a | Error e instance Functor (Result e) where map f (Ok a) = Ok (f a) map _ (Error e) = Error e instance Applicative (Result e) where apply (Ok f) a = map f a apply (Error e) _ = Error e pure = Ok instance Monad (Result e) where bind (Ok a) k = k a bind (Error e) _ = Error e instance (Show a, Show e) => Show (Result e a) where show (Ok x) = "Ok " ++ show x show (Error x) = "Error " ++ show x instance (Read a, Read e) => Read (Result e a) where read ['O'|['k'|[' '|xs]]] = Ok (read xs) read ['E'|['r'|['r'|['o'|['r'|[' '|xs]]]]]] = Error (read xs) read _ = error "not a Result" instance (Eq a, Eq e) => Eq (Result e a) where eq (Ok x) (Ok y) = eq x y eq (Error x) (Error y) = eq x y eq _ _ = false instance (Ord a, Ord e) => Ord (Result e a) where compare (Ok x) (Ok y) = compare x y compare (Error x) (Error y) = compare x y compare (Ok _) (Error _) = GT compare (Error _) (Ok _) = LT instance Semigroup (Result a b) where append (Ok a) _ = Ok a append _ a = a instance Foldable (Result a) where foldl f init (Ok x) = f init x foldl _ init (Error _) = init foldr f init (Ok x) = f x init foldr _ init (Error _) = init foldMap f (Ok x) = f x foldMap _ (Error _) = mempty instance Traversable (Result a) where traverse f (Ok x) = liftA1 Ok (f x) traverse _ (Error x) = pure (Error x) sequence (Ok x) = liftA1 Ok x sequence (Error x) = pure (Error x) isOk :: forall e a. Result e a -> Boolean isOk (Ok _) = true isOk _ = false isError :: forall e a. Result e a -> Boolean isError (Error _) = true isError _ = false fromOk :: forall e a. Result e a -> a fromOk (Ok a) = a fromOk (Error _) = error "Error" fromError :: forall e a. Result e a -> e fromError (Error e) = e fromError (Ok _) = error "Ok"