multi-except 0.1.4.0 → 0.2.0.0
raw patch · 6 files changed
+87/−8 lines, 6 filesdep +hspecdep +multi-exceptdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: hspec, multi-except
Dependency ranges changed: base
API changes (from Hackage documentation)
- Control.Applicative.MultiExcept: runMultiExcept :: MultiExcept err a -> Either (NonEmpty err) a
+ Control.Applicative.MultiExcept: runMultiExcept :: MultiExcept err a -> Either (DNonEmpty err) a
- Control.Applicative.MultiExcept: succeed :: a -> MultiExcept err a
+ Control.Applicative.MultiExcept: succeed :: forall err a. a -> MultiExcept err a
- Control.Applicative.MultiExcept: throwError :: err -> MultiExcept err a
+ Control.Applicative.MultiExcept: throwError :: forall a err. err -> MultiExcept err a
- Control.Applicative.MultiExcept: throwErrors :: DNonEmpty err -> MultiExcept err a
+ Control.Applicative.MultiExcept: throwErrors :: forall a err. DNonEmpty err -> MultiExcept err a
Files
- CHANGELOG.md +5/−0
- Control/Applicative/MultiExcept.hs +8/−7
- multi-except.cabal +12/−1
- test/Main.hs +14/−0
- test/Test/Applicative.hs +28/−0
- test/Test/Functor.hs +20/−0
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for multi-except +## 0.2.0.0 -- 2021-05-29++* Changed order of type variables in `succeed`+* Now required GHC >= 6.8.1 due to ScopedTypeVariables usage+ ## 0.1.4.0 -- 2021-05-26 * Added join, fromEitherPoly, throwErrors
Control/Applicative/MultiExcept.hs view
@@ -7,6 +7,8 @@ Portability : portable -} +{-# LANGUAGE ScopedTypeVariables #-}+ module Control.Applicative.MultiExcept ( MultiExcept , fromEither@@ -20,7 +22,6 @@ import Data.Functor.Alt import Data.DList.DNonEmpty (DNonEmpty)-import qualified Data.DList.DNonEmpty as DNE import Data.List.NonEmpty (NonEmpty) -- | A 'MultiExcept' is a success value, or one or more errors.@@ -30,21 +31,21 @@ deriving (Eq, Ord, Read, Show) -- | Run the computation.-runMultiExcept :: MultiExcept err a -> Either (NonEmpty err) a-runMultiExcept (Errors errs) = Left $ DNE.toNonEmpty errs+runMultiExcept :: MultiExcept err a -> Either (DNonEmpty err) a+runMultiExcept (Errors errs) = Left errs runMultiExcept (Success a) = Right a -- | Throw a single error.-throwError :: err -> MultiExcept err a+throwError :: forall a err. err -> MultiExcept err a throwError = Errors . pure -- | Throw one or more errors.-throwErrors :: DNonEmpty err -> MultiExcept err a+throwErrors :: forall a err. DNonEmpty err -> MultiExcept err a throwErrors = Errors -- | Embeds a value into a 'MultiExcept' context.-succeed :: a -> MultiExcept err a-succeed a = Success a+succeed :: forall err a. a -> MultiExcept err a+succeed = Success -- | Convert an 'Either' to a 'MultiExcept'. fromEither :: Either err a -> MultiExcept err a
multi-except.cabal view
@@ -1,7 +1,7 @@ cabal-version: >=1.10 name: multi-except-version: 0.1.4.0+version: 0.2.0.0 synopsis: Multiple Exceptions description: Exception type that supports reporting multiple exceptions license: MIT@@ -19,3 +19,14 @@ , dlist , semigroupoids default-language: Haskell2010++test-suite unit-tests+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Main.hs+ default-language: Haskell2010+ other-modules: Test.Functor+ , Test.Applicative+ build-depends: base+ , multi-except+ , hspec
+ test/Main.hs view
@@ -0,0 +1,14 @@+module Main where++import Test.Hspec++import qualified Test.Applicative+import qualified Test.Functor++main :: IO ()+main = hspec spec++spec :: Spec+spec = do+ Test.Functor.spec+ Test.Applicative.spec
+ test/Test/Applicative.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TupleSections #-}++module Test.Applicative+ ( spec+ ) where++import Test.Hspec++import Control.Applicative.MultiExcept++testErrors :: MultiExcept Int Int+testErrors = fromEitherPoly $ Left [2, 3]++spec :: Spec+spec = describe "Applicative instance" $ do+ describe "pure" $+ it "succeeds" $+ pure 5 `shouldBe` (succeed 5 :: MultiExcept () Int)+ describe "<*>" $ do+ it "accumulates errors" $+ throwError 2 <*> throwError 3 `shouldBe` testErrors+ it "propagates successes" $+ (,) <$> pure 3 <*> pure 4 `shouldBe` succeed @() (3, 4)+ it "errors when only one side is successful" $ do+ succeed (+ 1) <*> testErrors `shouldBe` testErrors+ throwError 2 <*> succeed () `shouldBe` throwError @Int 2
+ test/Test/Functor.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE TypeApplications #-}++module Test.Functor+ ( spec+ ) where++import Test.Hspec++import Control.Applicative.MultiExcept++testErrors :: MultiExcept Int Int+testErrors = fromEitherPoly (Left [2, 3])++spec :: Spec+spec = describe "Functor instance" $ do+ it "transforms success value" $+ ((+ 3) <$> succeed 2) `shouldBe` (succeed 5 :: MultiExcept () Int)+ it "doesn't affect errors" $ do+ fmap (+ 3) testErrors `shouldBe` testErrors