antelude-0.1.0: src/Antelude/Result.hs
{- |
Module : Antelude.Result
Description : Contains some functions for Results.
Maintainer : dneavesdev@pm.me
-}
module Antelude.Result
( Result (..)
, errWithDefault
, filterErrs
, filterOks
, fromEither
, fromMaybe
, isErr
, isOk
, mapErr
, mapOk
, okWithDefault
, partition
, result
) where
import safe Antelude.Function ( (.>) )
import safe Antelude.Internal.TypesClasses
( Bool (..)
, Either
, List
, Maybe
, Result (..)
)
import safe Antelude.List ( foldl' )
import safe Antelude.Tuple.Pair ( first, second )
import safe Prelude ( either, maybe, (++) )
-- | Convert a 'Either a b' to an 'Result a b'.
fromEither :: Either err ok -> Result err ok
fromEither = either Err Ok
-- | Convert a 'Maybe a' to an 'Result () a'.
fromMaybe :: Maybe ok -> Result () ok
fromMaybe = maybe (Err ()) Ok
-- | Map both cases of a 'Result a b' given two functions: one for the 'Err' case, and one for the 'Ok' case.
result :: (err -> a) -> (ok -> a) -> Result err ok -> a
result fnErr fnOk = \case
Ok ok -> fnOk ok
Err err -> fnErr err
-- | Map the 'Ok' case of a 'Result a b' given a function. Does not change an 'Err' case.
mapOk :: (ok -> newOk) -> Result err ok -> Result err newOk
mapOk fnOk = result Err (fnOk .> Ok)
-- | Map the 'Err' case of a 'Result a b' given a function. Does not change an 'Ok' case.
mapErr :: (err -> newErr) -> Result err ok -> Result newErr ok
mapErr fnErr = result (fnErr .> Err) Ok
-- | Test if the 'Result a b' is 'Ok'.
isOk :: Result err ok -> Bool
isOk = \case
Ok _ -> True
Err _ -> False
-- | Test if the 'Result a b' is 'Err'.
isErr :: Result err ok -> Bool
isErr = \case
Ok _ -> False
Err _ -> True
-- | Get the value of an 'Result a b', returns the 'Ok' value, or a default if 'Err'.
errWithDefault :: ok -> Result err ok -> ok
errWithDefault dflt = \case
Ok ok -> ok
Err _ -> dflt
-- | Get the value of an 'Result a b', returns the 'Err' value, or a default if 'Ok'.
okWithDefault :: err -> Result err ok -> err
okWithDefault dflt = \case
Ok _ -> dflt
Err err -> err
-- | Take a 'List' of 'Result err ok' and create a Tuple with 'List err' and 'List ok'.
partition :: List (Result err ok) -> (List ok, List err)
partition =
foldl'
( \acc res ->
case res of
Ok ok ->
(first acc ++ [ok], second acc)
Err err ->
(first acc, second acc ++ [err])
)
([], [])
-- | Take a 'List' of 'Result a b' and return a 'List' containing all of the values from the 'Ok' cases.
filterOks :: List (Result err ok) -> List ok
filterOks = partition .> first
-- | Take a 'List' of 'Result a b' and return a 'List' containing all of the values from the 'Err' cases.
filterErrs :: List (Result err ok) -> List err
filterErrs = partition .> second