either-result 0.3.1.0 → 0.3.2.0
raw patch · 17 files changed
+260/−210 lines, 17 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Control.Monad.Trans.Result: mapError :: (String -> String) -> Result a -> Result a
+ Control.Monad.Trans.Result: mapErrorT :: forall (m :: Type -> Type) a. Functor m => (String -> String) -> ResultT m a -> ResultT m a
+ Data.Either.Result: mapError :: (String -> String) -> Result a -> Result a
- Control.Monad.Result: data ResultT m a
+ Control.Monad.Result: data ResultT (m :: Type -> Type) a
- Control.Monad.Trans.Except.Result: ResultT :: ExceptT String m a -> ResultT m a
+ Control.Monad.Trans.Except.Result: ResultT :: ExceptT String m a -> ResultT (m :: Type -> Type) a
- Control.Monad.Trans.Except.Result: catchE :: Monad m => ResultT m a -> (String -> ResultT m a) -> ResultT m a
+ Control.Monad.Trans.Except.Result: catchE :: forall (m :: Type -> Type) a. Monad m => ResultT m a -> (String -> ResultT m a) -> ResultT m a
- Control.Monad.Trans.Except.Result: mapResultT :: (ExceptT String m a -> ExceptT String n b) -> ResultT m a -> ResultT n b
+ Control.Monad.Trans.Except.Result: mapResultT :: forall (m :: Type -> Type) a (n :: Type -> Type) b. (ExceptT String m a -> ExceptT String n b) -> ResultT m a -> ResultT n b
- Control.Monad.Trans.Except.Result: newtype ResultT m a
+ Control.Monad.Trans.Except.Result: newtype ResultT (m :: Type -> Type) a
- Control.Monad.Trans.Except.Result: throwE :: Monad m => String -> ResultT m a
+ Control.Monad.Trans.Except.Result: throwE :: forall (m :: Type -> Type) a. Monad m => String -> ResultT m a
- Control.Monad.Trans.Result: catchE :: Monad m => ResultT m a -> (String -> ResultT m a) -> ResultT m a
+ Control.Monad.Trans.Result: catchE :: forall (m :: Type -> Type) a. Monad m => ResultT m a -> (String -> ResultT m a) -> ResultT m a
- Control.Monad.Trans.Result: data ResultT m a
+ Control.Monad.Trans.Result: data ResultT (m :: Type -> Type) a
- Control.Monad.Trans.Result: throwE :: Monad m => String -> ResultT m a
+ Control.Monad.Trans.Result: throwE :: forall (m :: Type -> Type) a. Monad m => String -> ResultT m a
Files
- CHANGELOG.md +8/−0
- README.md +4/−2
- doctest/main.hs +0/−1
- either-result.cabal +17/−7
- spec/Control/Monad/ResultSpec.hs +0/−60
- spec/Control/Monad/Trans/Except/ResultSpec.hs +0/−55
- spec/Control/Monad/Trans/ResultSpec.hs +0/−72
- spec/Spec.hs +0/−1
- src/Control/Monad/Result.hs +6/−5
- src/Control/Monad/Trans/Except/Result.hs +10/−0
- src/Control/Monad/Trans/Result.hs +21/−3
- src/Data/Either/Result.hs +5/−4
- test/doctest/main.hs +1/−0
- test/spec/Control/Monad/ResultSpec.hs +60/−0
- test/spec/Control/Monad/Trans/Except/ResultSpec.hs +55/−0
- test/spec/Control/Monad/Trans/ResultSpec.hs +72/−0
- test/spec/Spec.hs +1/−0
CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for either-result +## 0.3.2.0++*2025.08.18*++- add COMPLETE Pragma for `Result` pattern+- add `mapError`+- make `Control.Monad.Result` re-export `Control.Monad.Error.Class`+ ## 0.3.1.0 *2020.08.16*
README.md view
@@ -1,5 +1,7 @@ # either-result -[](http://hackage.haskell.org/package/either-result) [](https://github.com/kakkun61/either-result/actions?query=workflow%3Atest) [](https://github.com/kakkun61/either-result/actions?query=workflow%3Alint) [](https://gitter.im/either-result/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://github.com/sponsors/kakkun61)+[](http://hackage.haskell.org/package/either-result) [](https://github.com/kakkun61/either-result/actions?query=workflow%3Amain) [](https://gitter.im/either-result/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://github.com/sponsors/kakkun61) -`Result a` is a wrapper of `Either String a`, but `Result` is an instance of `MonadFail`.+The simplest `MonadFail` instance. `Result a` is a wrapper of `Either String a`, but `Result` is an instance of `MonadFail`.++[Article](https://dev.to/kakkun61/the-simplest-monadfail-instance-2i4e).
− doctest/main.hs
@@ -1,1 +0,0 @@-{-# OPTIONS_GHC -F -pgmF doctest-discover #-}
either-result.cabal view
@@ -1,8 +1,8 @@ cabal-version: 2.2 name: either-result-version: 0.3.1.0-synopsis: ‘MonadFail’ instance for a wrapper of ‘ExceptT String m a’.+version: 0.3.2.0+synopsis: The simplest ‘MonadFail’ instance description: ‘ResultT m a’ is a wrapper of ‘ExceptT String m a’ which are similar except ‘MonadFail’ instance. homepage: https://github.com/kakkun61/either-result bug-reports: https://github.com/kakkun61/either-result/issues@@ -13,10 +13,19 @@ copyright: 2020 Kazuki Okamoto (岡本和樹) category: Data build-type: Simple-tested-with: GHC == 8.6.5, GHC == 8.8.3, GHC == 8.10.1-extra-source-files: README.md,- CHANGELOG.md+tested-with: GHC == 9.2.8, GHC == 9.4.4, GHC == 9.6.2+extra-doc-files: README.md,+ CHANGELOG.md +source-repository head+ type: git+ location: https://github.com/kakkun61/either-result.git++source-repository this+ type: git+ location: https://github.com/kakkun61/either-result.git+ tag: 0.3.2.0+ common common build-depends: base >= 4 && < 5 ghc-options: -Wall@@ -48,7 +57,7 @@ import: common type: exitcode-stdio-1.0 main-is: main.hs- hs-source-dirs: doctest+ hs-source-dirs: test/doctest build-depends: either-result, doctest ghc-options: -threaded@@ -60,7 +69,7 @@ import: common type: exitcode-stdio-1.0 main-is: Spec.hs- hs-source-dirs: spec+ hs-source-dirs: test/spec other-modules: Control.Monad.Trans.Except.ResultSpec, Control.Monad.Trans.ResultSpec, Control.Monad.ResultSpec@@ -70,4 +79,5 @@ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ -Wno-incomplete-uni-patterns build-tool-depends: hspec-discover:hspec-discover
− spec/Control/Monad/ResultSpec.hs
@@ -1,60 +0,0 @@-module Control.Monad.ResultSpec (spec) where--import Control.Monad.Result--import Test.Hspec--spec :: Spec-spec = do- describe "monad" $ do- it "runResult . Result == id" $ do- let e = pure 'a'- runResult (Result e) `shouldBe` e-- it "Result . runResult == id" $ do- let r = pure 'a'- Result (runResult r) `shouldBe` r-- it "b == a where Result b = Result a" $ do- let- a = pure 'a'- Result b = Result a- b `shouldBe` a-- it "result id id (Error e) == e" $ do- let e = "e"- result id id (Error e) `shouldBe` e-- it "result id id (Success a) == a" $ do- let a = "a"- result id id (Success a) `shouldBe` a-- it "fromSuccess b (Error e) == b" $ do- let b = "b"- fromSuccess b (Error "e") `shouldBe` b-- it "fromSuccess b (Success a) == a" $ do- let a = "a"- fromSuccess "b" (Success a) `shouldBe` a-- describe "monad transformer" $ do- it "runResultT . ResultT == id" $ do- let e = pure 'a'- runResult (Result e) `shouldBe` e-- it "Result . runResult == id" $ do- let r = pure 'a'- Result (runResult r) `shouldBe` r-- describe "exception" $ do- it "throwError e `catchError` pure == pure e" $ do- let- e = "err"- m = throwError e `catchError` pure :: Result String- m `shouldBe` pure e-- it "pure a `catchError` pure == pure a" $ do- let- a = "ok"- m = pure a `catchError` pure :: Result String- m `shouldBe` pure a
− spec/Control/Monad/Trans/Except/ResultSpec.hs
@@ -1,55 +0,0 @@-module Control.Monad.Trans.Except.ResultSpec (spec) where--import Control.Monad.Trans.Except.Result--import Test.Hspec--import Control.Monad.Trans.Except (ExceptT (ExceptT))-import Data.Coerce (coerce)-import Data.Functor.Identity (Identity (Identity))--spec :: Spec-spec = do- describe "monad" $ do- it "runResult . Result == id" $ do- let e = pure 'a'- runResult (Result e) `shouldBe` e-- it "Result . runResult == id" $ do- let r = pure 'a'- Result (runResult r) `shouldBe` r-- it "b == a where Result b = Result a" $ do- let- a = pure 'a'- Result b = Result a- b `shouldBe` a-- describe "coercible" $ do- it "Result Int -> Either String Int" $ do- let- actual = coerce $ Result $ pure (0 :: Int)- expected = Right 0 :: Either String Int- actual `shouldBe` expected-- describe "monad transformer" $ do- it "runResultT . ResultT == id" $ do- let e = pure 'a'- runResult (Result e) `shouldBe` e-- it "Result . runResult == id" $ do- let r = pure 'a'- Result (runResult r) `shouldBe` r-- describe "exception" $ do- it "throwE e `catchE` pure == pure e" $ do- let- e = "err"- m = throwE e `catchE` pure :: Result String- m `shouldBe` pure e-- it "pure a `catchE` pure == pure a" $ do- let- a = "ok"- m = pure a `catchE` pure :: Result String- m `shouldBe` pure a
− spec/Control/Monad/Trans/ResultSpec.hs
@@ -1,72 +0,0 @@-module Control.Monad.Trans.ResultSpec (spec) where--import Control.Monad.Trans.Result--import Test.Hspec--spec :: Spec-spec = do- describe "monad" $ do- it "runResult . Result == id" $ do- let e = pure 'a'- runResult (Result e) `shouldBe` e-- it "Result . runResult == id" $ do- let r = pure 'a'- Result (runResult r) `shouldBe` r-- it "b == a where Result b = Result a" $ do- let- a = pure 'a'- Result b = Result a- b `shouldBe` a-- it "result id id (Error e) == e" $ do- let e = "e"- result id id (Error e) `shouldBe` e-- it "result id id (Success a) == a" $ do- let a = "a"- result id id (Success a) `shouldBe` a-- it "fromSuccess b (Error e) == b" $ do- let b = "b"- fromSuccess b (Error "e") `shouldBe` b-- it "fromSuccess b (Success a) == a" $ do- let a = "a"- fromSuccess "b" (Success a) `shouldBe` a-- it "show (Error \"e\") == \"Error \\\"e\\\"\"" $ do- show (Error "e" :: Result Int) `shouldBe` "Error \"e\""-- it "show (Success 1) == \"Success 1\"" $ do- show (Success (1 :: Int)) `shouldBe` "Success 1"-- it "read \"Error \\\"e\\\"\" == Error \"e\"" $ do- read "Error \"e\"" `shouldBe` (Error "e" :: Result Int)-- it "read \"Success 1\" == Success 1" $ do- read "Success 1" `shouldBe` Success (1 :: Int)-- describe "monad transformer" $ do- it "runResultT . ResultT == id" $ do- let e = pure 'a'- runResult (Result e) `shouldBe` e-- it "Result . runResult == id" $ do- let r = pure 'a'- Result (runResult r) `shouldBe` r-- describe "exception" $ do- it "throwE e `catchE` pure == pure e" $ do- let- e = "err"- m = throwE e `catchE` pure :: Result String- m `shouldBe` pure e-- it "pure a `catchE` pure == pure a" $ do- let- a = "ok"- m = pure a `catchE` pure :: Result String- m `shouldBe` pure a
− spec/Spec.hs
@@ -1,1 +0,0 @@-{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
src/Control/Monad/Result.hs view
@@ -33,15 +33,16 @@ , module Control.Monad , module Control.Monad.Fix , module Control.Monad.Trans+ , module Control.Monad.Error.Class ) where -import Control.Monad.Error.Class (MonadError (catchError, throwError))-import Control.Monad.Trans.Except.Result (Result, ResultT)-import Control.Monad.Trans.Result (pattern Error, pattern Result, pattern ResultT, pattern Success,- catchE, fromEither, fromSuccess, mapResultT, result, runResult,- runResultT, throwE, toEither, toMonadFail)+import Control.Monad.Trans.Except.Result (Result, ResultT)+import Control.Monad.Trans.Result (catchE, fromEither, fromSuccess, mapResultT, pattern Error, pattern Result,+ pattern ResultT, pattern Success, result, runResult, runResultT, throwE,+ toEither, toMonadFail) import Control.Monad+import Control.Monad.Error.Class import Control.Monad.Fix import Control.Monad.Trans
src/Control/Monad/Trans/Except/Result.hs view
@@ -6,6 +6,16 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE PatternSynonyms #-} +#if __GLASGOW_HASKELL__ >= 906+-- To suppress:+--+-- src\Control\Monad\Trans\Except\Result.hs:81:21: warning: [GHC-30606] [-Wredundant-constraints]+-- • Redundant constraint: Eq a+-- • When deriving the instance for (Eq1 (ResultT m))+--+-- A newer 'transformers' package may fix this warning.+{-# OPTIONS_GHC -Wno-redundant-constraints #-}+#endif {-# OPTIONS_HADDOCK show-extensions #-} -- | This monad transformer extends a monad with the ability to fail.
src/Control/Monad/Trans/Result.hs view
@@ -21,11 +21,13 @@ , toEither , fromSuccess , toMonadFail+ , mapError -- * The ResultT monad transformer , type T.ResultT , pattern ResultT , runResultT , mapResultT+ , mapErrorT -- * Exception operations , T.throwE , T.catchE@@ -39,8 +41,8 @@ import qualified Control.Monad.Trans.Except.Result as T import Data.Functor.Identity (Identity (runIdentity)) import qualified GHC.Show as S-import Text.Read (Read (readPrec)) import qualified Text.Read as R+import Text.Read (Read (readPrec)) import qualified Text.Read.Lex as R #if !MIN_VERSION_base(4,13,0)@@ -70,7 +72,7 @@ instance Semigroup (T.Result a) where Error _ <> a = a- a <> _ = a+ a <> _ = a {-# INLINE (<>) #-} instance Monoid (T.Result a) where@@ -85,7 +87,9 @@ pattern Result r <- (runIdentity . runExceptT . T.runResultT -> r) where Result r = T.ResultT $ ExceptT $ pure r --- | Unrap @'T.Result' a@.+{-# COMPLETE Result #-}++-- | Unwrap @'T.Result' a@. runResult :: T.Result a -> Either String a runResult = runExcept . T.runResult {-# INLINE runResult #-}@@ -137,6 +141,11 @@ toMonadFail (Error e) = fail e {-# INLINE toMonadFail #-} +-- | Map the error in 'T.Result'.+mapError :: (String -> String) -> T.Result a -> T.Result a+mapError = mapErrorT+{-# INLINE mapError #-}+ -- | Construct and destruct 'T.Result'. pattern ResultT :: Functor m => m (T.Result a) -> T.ResultT m a pattern ResultT m <- ((Result <$>) . runExceptT . T.runResultT -> m)@@ -153,3 +162,12 @@ mapResultT :: (Functor m, Functor n) => (m (T.Result a) -> n (T.Result b)) -> T.ResultT m a -> T.ResultT n b mapResultT f = T.mapResultT $ T.runResultT . ResultT . f . runResultT . T.ResultT {-# INLINE mapResultT #-}++-- | Map the error in 'T.ResultT'.+mapErrorT :: Functor m => (String -> String) -> T.ResultT m a -> T.ResultT m a+mapErrorT f =+ mapResultT $ fmap go+ where+ go (Error e) = Error $ f e+ go a = a+{-# INLINE mapErrorT #-}
src/Data/Either/Result.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE ExplicitNamespaces #-}-{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ExplicitNamespaces #-}+{-# LANGUAGE PatternSynonyms #-} {-# OPTIONS_HADDOCK show-extensions #-} @@ -16,7 +16,8 @@ , toEither , fromSuccess , toMonadFail+ , mapError ) where -import Control.Monad.Trans.Result (pattern Error, pattern Result, type Result, pattern Success, fromEither,- fromSuccess, result, runResult, toEither, toMonadFail)+import Control.Monad.Trans.Result (fromEither, fromSuccess, mapError, pattern Error, pattern Result, pattern Success,+ result, runResult, toEither, toMonadFail, type Result)
+ test/doctest/main.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF doctest-discover #-}
+ test/spec/Control/Monad/ResultSpec.hs view
@@ -0,0 +1,60 @@+module Control.Monad.ResultSpec (spec) where++import Control.Monad.Result++import Test.Hspec++spec :: Spec+spec = do+ describe "monad" $ do+ it "runResult . Result == id" $ do+ let e = pure 'a'+ runResult (Result e) `shouldBe` e++ it "Result . runResult == id" $ do+ let r = pure 'a'+ Result (runResult r) `shouldBe` r++ it "b == a where Result b = Result a" $ do+ let+ a = pure 'a'+ Result b = Result a+ b `shouldBe` a++ it "result id id (Error e) == e" $ do+ let e = "e"+ result id id (Error e) `shouldBe` e++ it "result id id (Success a) == a" $ do+ let a = "a"+ result id id (Success a) `shouldBe` a++ it "fromSuccess b (Error e) == b" $ do+ let b = "b"+ fromSuccess b (Error "e") `shouldBe` b++ it "fromSuccess b (Success a) == a" $ do+ let a = "a"+ fromSuccess "b" (Success a) `shouldBe` a++ describe "monad transformer" $ do+ it "runResultT . ResultT == id" $ do+ let e = pure 'a'+ runResult (Result e) `shouldBe` e++ it "Result . runResult == id" $ do+ let r = pure 'a'+ Result (runResult r) `shouldBe` r++ describe "exception" $ do+ it "throwError e `catchError` pure == pure e" $ do+ let+ e = "err"+ m = throwError e `catchError` pure :: Result String+ m `shouldBe` pure e++ it "pure a `catchError` pure == pure a" $ do+ let+ a = "ok"+ m = pure a `catchError` pure :: Result String+ m `shouldBe` pure a
+ test/spec/Control/Monad/Trans/Except/ResultSpec.hs view
@@ -0,0 +1,55 @@+module Control.Monad.Trans.Except.ResultSpec (spec) where++import Control.Monad.Trans.Except.Result++import Test.Hspec++import Control.Monad.Trans.Except (ExceptT (ExceptT))+import Data.Coerce (coerce)+import Data.Functor.Identity (Identity (Identity))++spec :: Spec+spec = do+ describe "monad" $ do+ it "runResult . Result == id" $ do+ let e = pure 'a'+ runResult (Result e) `shouldBe` e++ it "Result . runResult == id" $ do+ let r = pure 'a'+ Result (runResult r) `shouldBe` r++ it "b == a where Result b = Result a" $ do+ let+ a = pure 'a'+ Result b = Result a+ b `shouldBe` a++ describe "coercible" $ do+ it "Result Int -> Either String Int" $ do+ let+ actual = coerce $ Result $ pure (0 :: Int)+ expected = Right 0 :: Either String Int+ actual `shouldBe` expected++ describe "monad transformer" $ do+ it "runResultT . ResultT == id" $ do+ let e = pure 'a'+ runResult (Result e) `shouldBe` e++ it "Result . runResult == id" $ do+ let r = pure 'a'+ Result (runResult r) `shouldBe` r++ describe "exception" $ do+ it "throwE e `catchE` pure == pure e" $ do+ let+ e = "err"+ m = throwE e `catchE` pure :: Result String+ m `shouldBe` pure e++ it "pure a `catchE` pure == pure a" $ do+ let+ a = "ok"+ m = pure a `catchE` pure :: Result String+ m `shouldBe` pure a
+ test/spec/Control/Monad/Trans/ResultSpec.hs view
@@ -0,0 +1,72 @@+module Control.Monad.Trans.ResultSpec (spec) where++import Control.Monad.Trans.Result++import Test.Hspec++spec :: Spec+spec = do+ describe "monad" $ do+ it "runResult . Result == id" $ do+ let e = pure 'a'+ runResult (Result e) `shouldBe` e++ it "Result . runResult == id" $ do+ let r = pure 'a'+ Result (runResult r) `shouldBe` r++ it "b == a where Result b = Result a" $ do+ let+ a = pure 'a'+ Result b = Result a+ b `shouldBe` a++ it "result id id (Error e) == e" $ do+ let e = "e"+ result id id (Error e) `shouldBe` e++ it "result id id (Success a) == a" $ do+ let a = "a"+ result id id (Success a) `shouldBe` a++ it "fromSuccess b (Error e) == b" $ do+ let b = "b"+ fromSuccess b (Error "e") `shouldBe` b++ it "fromSuccess b (Success a) == a" $ do+ let a = "a"+ fromSuccess "b" (Success a) `shouldBe` a++ it "show (Error \"e\") == \"Error \\\"e\\\"\"" $ do+ show (Error "e" :: Result Int) `shouldBe` "Error \"e\""++ it "show (Success 1) == \"Success 1\"" $ do+ show (Success (1 :: Int)) `shouldBe` "Success 1"++ it "read \"Error \\\"e\\\"\" == Error \"e\"" $ do+ read "Error \"e\"" `shouldBe` (Error "e" :: Result Int)++ it "read \"Success 1\" == Success 1" $ do+ read "Success 1" `shouldBe` Success (1 :: Int)++ describe "monad transformer" $ do+ it "runResultT . ResultT == id" $ do+ let e = pure 'a'+ runResult (Result e) `shouldBe` e++ it "Result . runResult == id" $ do+ let r = pure 'a'+ Result (runResult r) `shouldBe` r++ describe "exception" $ do+ it "throwE e `catchE` pure == pure e" $ do+ let+ e = "err"+ m = throwE e `catchE` pure :: Result String+ m `shouldBe` pure e++ it "pure a `catchE` pure == pure a" $ do+ let+ a = "ok"+ m = pure a `catchE` pure :: Result String+ m `shouldBe` pure a
+ test/spec/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}