multi-except 0.2.0.0 → 0.2.1.0
raw patch · 10 files changed
+111/−4 lines, 10 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Applicative.MultiExcept: instance Data.Bifunctor.Bifunctor Control.Applicative.MultiExcept.MultiExcept
+ Control.Applicative.MultiExcept: instance Data.Foldable.Foldable (Control.Applicative.MultiExcept.MultiExcept err)
+ Control.Applicative.MultiExcept: instance Data.Traversable.Traversable (Control.Applicative.MultiExcept.MultiExcept err)
Files
- CHANGELOG.md +6/−0
- Control/Applicative/MultiExcept.hs +13/−1
- multi-except.cabal +6/−1
- test/Main.hs +8/−0
- test/Test/Alt.hs +22/−0
- test/Test/Applicative.hs +1/−1
- test/Test/Bifunctor.hs +18/−0
- test/Test/Foldable.hs +17/−0
- test/Test/Functor.hs +1/−1
- test/Test/Traversable.hs +19/−0
CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for multi-except +## 0.2.1.0 -- 2021-05-31++* Added Bifunctor instance+* Added Foldable instance+* Added Traversable instance+ ## 0.2.0.0 -- 2021-05-29 * Changed order of type variables in `succeed`
Control/Applicative/MultiExcept.hs view
@@ -20,9 +20,9 @@ , throwErrors ) where +import Data.Bifunctor import Data.Functor.Alt import Data.DList.DNonEmpty (DNonEmpty)-import Data.List.NonEmpty (NonEmpty) -- | A 'MultiExcept' is a success value, or one or more errors. data MultiExcept err a@@ -68,6 +68,10 @@ fmap f (Success a) = Success $ f a fmap _ (Errors errs) = Errors errs +instance Bifunctor MultiExcept where+ bimap _ fa (Success a) = Success $ fa a+ bimap ferr _ (Errors err) = Errors $ fmap ferr err+ instance Applicative (MultiExcept err) where pure = Success @@ -80,3 +84,11 @@ Success a <!> _ = Success a _ <!> Success a = Success a Errors l <!> Errors r = Errors (l <> r)++instance Foldable (MultiExcept err) where+ foldr f acc (Success a) = f a acc+ foldr _ acc _ = acc++instance Traversable (MultiExcept err) where+ traverse f (Success a) = Success <$> f a+ traverse _ (Errors err) = pure $ Errors err
multi-except.cabal view
@@ -1,7 +1,7 @@ cabal-version: >=1.10 name: multi-except-version: 0.2.0.0+version: 0.2.1.0 synopsis: Multiple Exceptions description: Exception type that supports reporting multiple exceptions license: MIT@@ -27,6 +27,11 @@ default-language: Haskell2010 other-modules: Test.Functor , Test.Applicative+ , Test.Alt+ , Test.Bifunctor+ , Test.Foldable+ , Test.Traversable build-depends: base , multi-except+ , semigroupoids , hspec
test/Main.hs view
@@ -3,7 +3,11 @@ import Test.Hspec import qualified Test.Applicative+import qualified Test.Alt import qualified Test.Functor+import qualified Test.Bifunctor+import qualified Test.Foldable+import qualified Test.Traversable main :: IO () main = hspec spec@@ -12,3 +16,7 @@ spec = do Test.Functor.spec Test.Applicative.spec+ Test.Alt.spec+ Test.Bifunctor.spec+ Test.Foldable.spec+ Test.Traversable.spec
+ test/Test/Alt.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE TypeApplications #-}++module Test.Alt+ ( spec+ ) where++import Test.Hspec++import Data.Functor.Alt+import Control.Applicative.MultiExcept++spec :: Spec+spec = describe "Alt instance" $ do+ it "propagates left succeed" $+ succeed 1 <!> throwError 3 `shouldBe` succeed 1+ it "propagates right succeed" $+ throwError () <!> succeed 1 `shouldBe` succeed 1+ it "prioritizes left succeed" $+ succeed 1 <!> succeed 2 `shouldBe` succeed @() 1+ it "propagates both errors" $ do+ throwError 1 <!> throwError 2`shouldBe` throwErrors @() [1, 2]
test/Test/Applicative.hs view
@@ -22,7 +22,7 @@ it "accumulates errors" $ throwError 2 <*> throwError 3 `shouldBe` testErrors it "propagates successes" $- (,) <$> pure 3 <*> pure 4 `shouldBe` succeed @() (3, 4)+ 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/Bifunctor.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE TypeApplications #-}++module Test.Bifunctor+ ( spec+ ) where++import Test.Hspec++import Data.Bifunctor+import Control.Applicative.MultiExcept++spec :: Spec+spec = describe "Bifunctor instance" $ do+ it "maps errors with first" $+ first (+ 1) (throwErrors [3, 4]) `shouldBe` throwErrors @() [4, 5]+ it "maps successes with second" $+ second (+ 1) (succeed 3) `shouldBe` succeed @() 4
+ test/Test/Foldable.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE TypeApplications #-}++module Test.Foldable+ ( spec+ ) where++import Test.Hspec++import Control.Applicative.MultiExcept++spec :: Spec+spec = describe "Foldable instance" $ do+ it "f is called for success" $+ foldr (+) 2 (succeed 1)`shouldBe` 3+ it "acc is returned for errors" $+ foldr (+) 2 (throwError 1)`shouldBe` 2
test/Test/Functor.hs view
@@ -15,6 +15,6 @@ spec :: Spec spec = describe "Functor instance" $ do it "transforms success value" $- ((+ 3) <$> succeed 2) `shouldBe` (succeed 5 :: MultiExcept () Int)+ ((+ 3) <$> succeed 2) `shouldBe` succeed @() 5 it "doesn't affect errors" $ do fmap (+ 3) testErrors `shouldBe` testErrors
+ test/Test/Traversable.hs view
@@ -0,0 +1,19 @@+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE TypeApplications #-}++module Test.Traversable+ ( spec+ ) where++import Test.Hspec++import Control.Applicative.MultiExcept++spec :: Spec+spec = describe "Traversable instance" $ do+ it "Just works™" $+ traverse Just (succeed 3) `shouldBe` Just (succeed @() 3)+ it "leaves errors" $+ traverse Just (throwError 3) `shouldBe` Just (throwError @() 3)+ it "Nothing works™" $+ traverse (const Nothing :: a -> Maybe a) (succeed @() 3) `shouldBe` Nothing