Hello community,

here is the log from the commit of package ghc-either for openSUSE:Factory 
checked in at 2018-05-30 12:07:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-either (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-either.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-either"

Wed May 30 12:07:07 2018 rev:9 rq:607792 version:5

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-either/ghc-either.changes    2017-09-15 
21:37:23.491278756 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-either.new/ghc-either.changes       
2018-05-30 12:25:35.101778317 +0200
@@ -1,0 +2,13 @@
+Mon May 14 17:02:11 UTC 2018 - psim...@suse.com
+
+- Update either to version 5.
+  * Changed the semantics of the `Validation` `Alt` and `Alternative` 
instances to collect errors.
+    The previous implementation did not correctly abide the laws.
+  * Added `vap`, for when users want validation like semantics but don't want 
to convert back and forth to validation all the time. Similarly, added `ealt` 
to give either's `Alt` semantics to validation.
+  * Dropped the deprecated `Control.Monad.Trans.Either`.  Use 
`Control.Monad.Trans.Except` from `transformers` and/or
+    `transformers-compat` instead.
+  * Add `MMonad` instance for `EitherT`
+  * Deprecate `Control.Monad.Trans.Either` in favor of 
`Control.Monad.Trans.Except`
+  * Add `firstEitherT`
+
+-------------------------------------------------------------------

Old:
----
  either-4.4.1.1.tar.gz
  either.cabal

New:
----
  either-5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-either.spec ++++++
--- /var/tmp/diff_new_pack.PkpGKd/_old  2018-05-30 12:25:35.981749258 +0200
+++ /var/tmp/diff_new_pack.PkpGKd/_new  2018-05-30 12:25:35.985749126 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-either
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,32 +17,28 @@
 
 
 %global pkg_name either
+%bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        4.4.1.1
+Version:        5
 Release:        0
-Summary:        An either monad transformer
+Summary:        Combinators for working with sums
 License:        BSD-3-Clause
 Group:          Development/Libraries/Haskell
 URL:            https://hackage.haskell.org/package/%{pkg_name}
 Source0:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
-Source1:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/2.cabal#/%{pkg_name}.cabal
 BuildRequires:  ghc-Cabal-devel
-BuildRequires:  ghc-MonadRandom-devel
 BuildRequires:  ghc-bifunctors-devel
-BuildRequires:  ghc-exceptions-devel
-BuildRequires:  ghc-free-devel
-BuildRequires:  ghc-mmorph-devel
-BuildRequires:  ghc-monad-control-devel
 BuildRequires:  ghc-mtl-devel
 BuildRequires:  ghc-profunctors-devel
 BuildRequires:  ghc-rpm-macros
 BuildRequires:  ghc-semigroupoids-devel
 BuildRequires:  ghc-semigroups-devel
-BuildRequires:  ghc-transformers-base-devel
-BuildRequires:  ghc-transformers-devel
+%if %{with tests}
+BuildRequires:  ghc-hedgehog-devel
+%endif
 
 %description
-An either monad transformer.
+Combinators for working with sums.
 
 %package devel
 Summary:        Haskell %{pkg_name} library development files
@@ -57,7 +53,6 @@
 
 %prep
 %setup -q -n %{pkg_name}-%{version}
-cp -p %{SOURCE1} %{pkg_name}.cabal
 
 %build
 %ghc_lib_build
@@ -65,6 +60,9 @@
 %install
 %ghc_lib_install
 
+%check
+%cabal_test
+
 %post devel
 %ghc_pkg_recache
 
@@ -72,7 +70,7 @@
 %ghc_pkg_recache
 
 %files -f %{name}.files
-%doc LICENSE
+%license LICENSE
 
 %files devel -f %{name}-devel.files
 %doc CHANGELOG.markdown README.markdown

++++++ either-4.4.1.1.tar.gz -> either-5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/either-4.4.1.1/.gitignore new/either-5/.gitignore
--- old/either-4.4.1.1/.gitignore       2016-05-10 01:31:19.000000000 +0200
+++ new/either-5/.gitignore     2017-11-21 04:04:46.000000000 +0100
@@ -11,3 +11,5 @@
 *.hi
 *~
 *#
+.cabal-sandbox/
+cabal.sandbox.config
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/either-4.4.1.1/.travis.yml new/either-5/.travis.yml
--- old/either-4.4.1.1/.travis.yml      2016-05-10 01:31:19.000000000 +0200
+++ new/either-5/.travis.yml    2017-11-21 04:04:46.000000000 +0100
@@ -1,8 +1,104 @@
-language: haskell
+# This file has been generated -- see https://github.com/hvr/multi-ghc-travis
+language: c
+sudo: false
+
+cache:
+  directories:
+    - $HOME/.cabsnap
+    - $HOME/.cabal/packages
+
+before_cache:
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
+
+matrix:
+  include:
+    - env: CABALVER=1.18 GHCVER=7.4.2
+      compiler: ": #GHC 7.4.2"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.4.2], sources: 
[hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.6.3
+      compiler: ": #GHC 7.6.3"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.6.3], sources: 
[hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.8.4
+      compiler: ": #GHC 7.8.4"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: 
[hvr-ghc]}}
+    - env: CABALVER=1.22 GHCVER=7.10.3
+      compiler: ": #GHC 7.10.3"
+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: 
[hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=8.0.2
+      compiler: ": #GHC 8.0.2"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2], sources: 
[hvr-ghc]}}
+    - env: CABALVER=2.0 GHCVER=8.2.1
+      compiler: ": #GHC 8.2.1"
+      addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.1], sources: 
[hvr-ghc]}}
+    - env: CABALVER=head GHCVER=head
+      compiler: ": #GHC head"
+      addons: {apt: {packages: [cabal-install-head,ghc-head], sources: 
[hvr-ghc]}}
+
+  allow_failures:
+    - env: CABALVER=head GHCVER=head
+
+before_install:
+ - unset CC
+ - export 
PATH=$HOME/.cabal/bin:/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
+
+install:
+ - cabal --version
+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || 
echo '?')]"
+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
+   then
+     zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
+          $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
+   fi
+ - travis_retry cabal update -v
+ - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
+ - cabal install --only-dependencies --dry -v > installplan.txt
+ - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
+
+# check whether current requested install-plan matches cached package-db 
snapshot
+ - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;
+   then
+     echo "cabal build-cache HIT";
+     rm -rfv .ghc;
+     cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
+     cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin 
$HOME/.cabal/;
+   else
+     echo "cabal build-cache MISS";
+     rm -rf $HOME/.cabsnap;
+     mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
+     cabal install -j --only-dependencies;
+   fi
+
+# snapshot package-db on cache miss
+ - if [ ! -d $HOME/.cabsnap ];
+   then
+      echo "snapshotting package-db to build-cache";
+      mkdir $HOME/.cabsnap;
+      cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
+      cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin 
installplan.txt $HOME/.cabsnap/;
+   fi
+
+# Here starts the actual work to be performed for the package under test;
+# any command which exits with a non-zero exit code causes the build to fail.
+script:
+ - cabal configure -v2 # -v2 provides useful information for debugging
+ - cabal build # this builds all libraries and executables (including 
tests/benchmarks)
+ - cabal sdist   # tests that a source-distribution can be generated
+ - export SRC_TGZ=$(cabal info . | awk '{print $2 ".tar.gz";exit}') ;
+   cd dist/;
+   if [ -f "$SRC_TGZ" ]; then
+      cabal install "$SRC_TGZ";
+   else
+      echo "expected '$SRC_TGZ' not found";
+      exit 1;
+   fi
+
 notifications:
   irc:
     channels:
       - "irc.freenode.org#haskell-lens"
     skip_join: true
     template:
-      - "\x0313either\x03/\x0306%{branch}\x03 \x0314%{commit}\x03 %{build_url} 
%{message}"
+      - "\x0313either\x0f/\x0306%{branch}\x0f \x0314%{commit}\x0f %{message} 
\x0302\x1f%{build_url}\x0f"
+
+# EOF
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/either-4.4.1.1/CHANGELOG.markdown 
new/either-5/CHANGELOG.markdown
--- old/either-4.4.1.1/CHANGELOG.markdown       2016-05-10 01:31:19.000000000 
+0200
+++ new/either-5/CHANGELOG.markdown     2017-11-21 04:04:46.000000000 +0100
@@ -1,3 +1,17 @@
+5
+-
+* Changed the semantics of the `Validation` `Alt` and `Alternative` instances 
to collect errors.
+  The previous implementation did not correctly abide the laws.
+* Added `vap`, for when users want validation like semantics but don't want to 
convert back and forth to validation all the time. Similarly, added `ealt` to 
give either's `Alt` semantics to validation.
+* Dropped the deprecated `Control.Monad.Trans.Either`.  Use 
`Control.Monad.Trans.Except` from `transformers` and/or
+  `transformers-compat` instead.
+
+4.5
+----
+* Add `MMonad` instance for `EitherT`
+* Deprecate `Control.Monad.Trans.Either` in favor of 
`Control.Monad.Trans.Except`
+* Add `firstEitherT`
+
 4.4.1.1
 -------
 * Fixed building on newer GHCs. (type synonyms require explicit foralls for 
unused variables these days)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/either-4.4.1.1/either.cabal new/either-5/either.cabal
--- old/either-4.4.1.1/either.cabal     2016-05-10 01:31:19.000000000 +0200
+++ new/either-5/either.cabal   2017-11-21 04:04:46.000000000 +0100
@@ -1,17 +1,17 @@
 name:          either
 category:      Control, Monads
-version:       4.4.1.1
+version:       5
 license:       BSD3
-cabal-version: >= 1.6
+cabal-version: >= 1.10
 license-file:  LICENSE
 author:        Edward A. Kmett
 maintainer:    Edward A. Kmett <ekm...@gmail.com>
 stability:     provisional
 homepage:      http://github.com/ekmett/either/
 bug-reports:   http://github.com/ekmett/either/issues
-copyright:     Copyright (C) 2008-2014 Edward A. Kmett
-synopsis:      An either monad transformer
-description:   An either monad transformer
+copyright:     Copyright (C) 2008-2017 Edward A. Kmett
+synopsis:      Combinators for working with sums
+description:   Combinators for working with sums.
 build-type:    Simple
 extra-source-files:
   .gitignore
@@ -29,21 +29,23 @@
   build-depends:
     base              >= 4       && < 5,
     bifunctors        >= 4       && < 6,
-    exceptions        >= 0.5     && < 0.9,
-    free              >= 4.9     && < 5,
-    monad-control     >= 0.3.2   && < 1.1,
-    MonadRandom       >= 0.1     && < 0.5,
     mtl               >= 2.0     && < 2.3,
-    mmorph            >= 1.0.0   && < 1.1,
     profunctors       >= 4       && < 6,
     semigroups        >= 0.8.3.1 && < 1,
-    semigroupoids     >= 4       && < 6,
-    transformers      >= 0.2     && < 0.6,
-    transformers-base >= 0.4     && < 0.5
+    semigroupoids     >= 4       && < 6
 
-  extensions: CPP
-  exposed-modules: Control.Monad.Trans.Either
-                   Data.Either.Combinators
-                   Data.Either.Validation
+  other-extensions: CPP Rank2Types
   ghc-options: -Wall
   hs-source-dirs: src
+  default-language: Haskell2010
+  exposed-modules:
+    Data.Either.Combinators
+    Data.Either.Validation
+
+test-suite tests
+  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  hs-source-dirs: tests
+  build-depends: base, either, hedgehog
+  default-language: Haskell2010
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/either-4.4.1.1/src/Control/Monad/Trans/Either.hs 
new/either-5/src/Control/Monad/Trans/Either.hs
--- old/either-4.4.1.1/src/Control/Monad/Trans/Either.hs        2016-05-10 
01:31:19.000000000 +0200
+++ new/either-5/src/Control/Monad/Trans/Either.hs      1970-01-01 
01:00:00.000000000 +0100
@@ -1,360 +0,0 @@
-{-# LANGUAGE CPP #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Trustworthy #-}
-#endif
-
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE FlexibleContexts      #-}
-{-# LANGUAGE UndecidableInstances  #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE TypeFamilies #-}
------------------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Trans.Either
--- Copyright   :  (C) 2008-2014 Edward Kmett
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  Edward Kmett <ekm...@gmail.com>
--- Stability   :  provisional
--- Portability :  MPTCs
---
--- This module provides a minimalist 'Either' monad transformer.
------------------------------------------------------------------------------
-
-module Control.Monad.Trans.Either
-  ( EitherT(..)
-  , eitherT
-  , bimapEitherT
-  , mapEitherT
-  , hoistEither
-  , bracketEitherT
-  , bracketEitherT_
-  , left
-  , right
-  , swapEitherT
-  ) where
-
-import Control.Applicative
-import Control.Monad (liftM, MonadPlus(..))
-import Control.Monad.Base (MonadBase(..), liftBaseDefault)
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Free.Class
-import Control.Monad.Catch as MonadCatch
-import Control.Monad.Fix
-import Control.Monad.IO.Class
-import Control.Monad.Reader.Class
-import Control.Monad.State (MonadState,get,put)
-import Control.Monad.Trans.Class
-import Control.Monad.Trans.Control (MonadBaseControl(..), 
MonadTransControl(..), defaultLiftBaseWith, defaultRestoreM)
-import Control.Monad.Writer.Class
-import Control.Monad.Random 
(MonadRandom,getRandom,getRandoms,getRandomR,getRandomRs)
-import Control.Monad.Morph (MFunctor, hoist)
-import Data.Either.Combinators ( swapEither )
-import Data.Foldable
-import Data.Function (on)
-import Data.Functor.Bind
-import Data.Functor.Plus
-import Data.Traversable
-import Data.Semigroup
-
--- | 'EitherT' is a version of 'Control.Monad.Trans.Error.ErrorT' that does not
--- require a spurious 'Control.Monad.Error.Class.Error' instance for the 'Left'
--- case.
---
--- 'Either' is a perfectly usable 'Monad' without such a constraint. 'ErrorT' 
is
--- not the generalization of the current 'Either' monad, it is something else.
---
--- This is necessary for both theoretical and practical reasons. For instance 
an
--- apomorphism is the generalized anamorphism for this Monad, but it cannot be
--- written with 'ErrorT'.
---
--- In addition to the combinators here, the @errors@ package provides a large
--- number of combinators for working with this type.
-newtype EitherT e m a = EitherT { runEitherT :: m (Either e a) }
-
-instance Show (m (Either e a)) => Show (EitherT e m a) where
-  showsPrec d (EitherT m) = showParen (d > 10) $
-    showString "EitherT " . showsPrec 11 m
-  {-# INLINE showsPrec #-}
-
-instance Read (m (Either e a)) => Read (EitherT e m a) where
-  readsPrec d = readParen (d > 10)
-    (\r' -> [ (EitherT m, t)
-            | ("EitherT", s) <- lex r'
-            , (m, t) <- readsPrec 11 s])
-  {-# INLINE readsPrec #-}
-
-instance Eq (m (Either e a)) => Eq (EitherT e m a) where
-  (==) = (==) `on` runEitherT
-  {-# INLINE (==) #-}
-
-instance Ord (m (Either e a)) => Ord (EitherT e m a) where
-  compare = compare `on` runEitherT
-  {-# INLINE compare #-}
-
-instance MFunctor (EitherT e) where
-  hoist f = EitherT . f . runEitherT
-  {-# INLINE hoist #-}
-
--- | Given a pair of actions, one to perform in case of failure, and one to 
perform
--- in case of success, run an 'EitherT' and get back a monadic result.
-eitherT :: Monad m => (a -> m c) -> (b -> m c) -> EitherT a m b -> m c
-eitherT f g (EitherT m) = m >>= \z -> case z of
-  Left a -> f a
-  Right b -> g b
-{-# INLINE eitherT #-}
-
--- | Analogous to 'Left'. Equivalent to 'throwError'.
-left :: Monad m => e -> EitherT e m a
-left = EitherT . return . Left
-{-# INLINE left #-}
-
--- | Analogous to 'Right'. Equivalent to 'return'.
-right :: Monad m => a -> EitherT e m a
-right = return
-{-# INLINE right #-}
-
--- | Map over both failure and success.
-bimapEitherT :: Functor m => (e -> f) -> (a -> b) -> EitherT e m a -> EitherT 
f m b
-bimapEitherT f g (EitherT m) = EitherT (fmap h m) where
-  h (Left e)  = Left (f e)
-  h (Right a) = Right (g a)
-{-# INLINE bimapEitherT #-}
-
--- | Map the unwrapped computation using the given function.
---
--- @
--- 'runEitherT' ('mapEitherT' f m) = f ('runEitherT' m)
--- @
-mapEitherT :: (m (Either e a) -> n (Either e' b)) -> EitherT e m a -> EitherT 
e' n b
-mapEitherT f m = EitherT $ f (runEitherT m)
-{-# INLINE mapEitherT #-}
-
--- | Lift an 'Either' into an 'EitherT'
-hoistEither :: Monad m => Either e a -> EitherT e m a
-hoistEither = EitherT . return
-{-# INLINE hoistEither #-}
-
--- | Acquire a resource in 'EitherT' and then perform an action with it,
--- cleaning up afterwards regardless of error. Like
--- 'Control.Exception.bracket', but acting only in 'EitherT'.
-bracketEitherT :: Monad m => EitherT e m a -> (a -> EitherT e m b) -> (a -> 
EitherT e m c) -> EitherT e m c
-bracketEitherT before after thing = do
-    a <- before
-    r <- thing a `catchError` (\err -> after a >> left err)
-    -- If catchError already triggered, then `after` already ran *and* we are
-    -- in a Left state, so `after` will not run again here.
-    _ <- after a
-    return r
-
--- | Version of 'bracketEitherT' which discards the result from the initial
--- action.
-bracketEitherT_ :: Monad m => EitherT e m a -> EitherT e m b -> EitherT e m c 
-> EitherT e m c
-bracketEitherT_ before after thing = do
-    _ <- before
-    r <- thing `catchError` (\err -> after >> left err)
-    -- If catchError already triggered, then `after` already ran *and* we are
-    -- in a Left state, so `after` will not run again here.
-    _ <- after
-    return r
-
--- | Monad transformer version of 'swapEither'.
-swapEitherT :: (Functor m) => EitherT e m a -> EitherT a m e
-swapEitherT = EitherT . fmap swapEither . runEitherT
-{-# INLINE swapEitherT #-}
-
-instance Monad m => Functor (EitherT e m) where
-  fmap f = EitherT . liftM (fmap f) . runEitherT
-  {-# INLINE fmap #-}
-
-instance Monad m => Apply (EitherT e m) where
-  EitherT f <.> EitherT v = EitherT $ f >>= \mf -> case mf of
-    Left  e -> return (Left e)
-    Right k -> v >>= \mv -> case mv of
-      Left  e -> return (Left e)
-      Right x -> return (Right (k x))
-  {-# INLINE (<.>) #-}
-
-instance Monad m => Applicative (EitherT e m) where
-  pure a  = EitherT $ return (Right a)
-  {-# INLINE pure #-}
-  EitherT f <*> EitherT v = EitherT $ f >>= \mf -> case mf of
-    Left  e -> return (Left e)
-    Right k -> v >>= \mv -> case mv of
-      Left  e -> return (Left e)
-      Right x -> return (Right (k x))
-  {-# INLINE (<*>) #-}
-
-instance (Monad m, Monoid e) => Alternative (EitherT e m) where
-  EitherT m <|> EitherT n = EitherT $ m >>= \a -> case a of
-    Left l -> liftM (\b -> case b of
-      Left l' -> Left (mappend l l')
-      Right r -> Right r) n
-    Right r -> return (Right r)
-  {-# INLINE (<|>) #-}
-
-  empty = EitherT $ return (Left mempty)
-  {-# INLINE empty #-}
-
-instance (Monad m, Monoid e) => MonadPlus (EitherT e m) where
-  mplus = (<|>)
-  {-# INLINE mplus #-}
-
-  mzero = empty
-  {-# INLINE mzero #-}
-
-instance Monad m => Semigroup (EitherT e m a) where
-  EitherT m <> EitherT n = EitherT $ m >>= \a -> case a of
-    Left _  -> n
-    Right r -> return (Right r)
-  {-# INLINE (<>) #-}
-
-instance (Monad m, Semigroup e) => Alt (EitherT e m) where
-  EitherT m <!> EitherT n = EitherT $ m >>= \a -> case a of
-    Left l -> liftM (\b -> case b of
-      Left l' -> Left (l <> l')
-      Right r -> Right r) n
-    Right r -> return (Right r)
-  {-# INLINE (<!>) #-}
-
-instance Monad m => Bind (EitherT e m) where
-  (>>-) = (>>=)
-  {-# INLINE (>>-) #-}
-
-instance Monad m => Monad (EitherT e m) where
-  return a = EitherT $ return (Right a)
-  {-# INLINE return #-}
-  m >>= k  = EitherT $ do
-    a <- runEitherT m
-    case a of
-      Left  l -> return (Left l)
-      Right r -> runEitherT (k r)
-  {-# INLINE (>>=) #-}
-  fail = EitherT . fail
-  {-# INLINE fail #-}
-
-instance Monad m => MonadError e (EitherT e m) where
-  throwError = EitherT . return . Left
-  {-# INLINE throwError #-}
-  EitherT m `catchError` h = EitherT $ m >>= \a -> case a of
-    Left  l -> runEitherT (h l)
-    Right r -> return (Right r)
-  {-# INLINE catchError #-}
-
--- | Throws exceptions into the base monad.
-instance MonadThrow m => MonadThrow (EitherT e m) where
-  throwM = lift . throwM
-  {-# INLINE throwM #-}
-
--- | Catches exceptions from the base monad.
-instance MonadCatch m => MonadCatch (EitherT e m) where
-  catch (EitherT m) f = EitherT $ MonadCatch.catch m (runEitherT . f)
-  {-# INLINE catch #-}
-
-instance MonadFix m => MonadFix (EitherT e m) where
-  mfix f = EitherT $ mfix $ \a -> runEitherT $ f $ case a of
-    Right r -> r
-    _       -> error "empty mfix argument"
-  {-# INLINE mfix #-}
-
-instance MonadTrans (EitherT e) where
-  lift = EitherT . liftM Right
-  {-# INLINE lift #-}
-
-instance MonadIO m => MonadIO (EitherT e m) where
-  liftIO = lift . liftIO
-  {-# INLINE liftIO #-}
-
-instance MonadCont m => MonadCont (EitherT e m) where
-  callCC f = EitherT $
-    callCC $ \c ->
-    runEitherT (f (\a -> EitherT $ c (Right a)))
-  {-# INLINE callCC #-}
-
-instance MonadReader r m => MonadReader r (EitherT e m) where
-  ask = lift ask
-  {-# INLINE ask #-}
-  local f (EitherT m) = EitherT (local f m)
-  {-# INLINE local #-}
-
-instance MonadState s m => MonadState s (EitherT e m) where
-  get = lift get
-  {-# INLINE get #-}
-  put = lift . put
-  {-# INLINE put #-}
-
-instance MonadWriter s m => MonadWriter s (EitherT e m) where
-  tell = lift . tell
-  {-# INLINE tell #-}
-  listen = mapEitherT $ \ m -> do
-    (a, w) <- listen m
-    return $! fmap (\ r -> (r, w)) a
-  {-# INLINE listen #-}
-  pass = mapEitherT $ \ m -> pass $ do
-    a <- m
-    return $! case a of
-        Left  l      -> (Left  l, id)
-        Right (r, f) -> (Right r, f)
-  {-# INLINE pass #-}
-
-instance MonadRandom m => MonadRandom (EitherT e m) where
-  getRandom   = lift getRandom
-  {-# INLINE getRandom #-}
-  getRandoms  = lift getRandoms
-  {-# INLINE getRandoms #-}
-  getRandomR  = lift . getRandomR
-  {-# INLINE getRandomR #-}
-  getRandomRs = lift . getRandomRs
-  {-# INLINE getRandomRs #-}
-
-instance Foldable m => Foldable (EitherT e m) where
-  foldMap f = foldMap (either mempty f) . runEitherT
-  {-# INLINE foldMap #-}
-
-instance (Functor f, MonadFree f m) => MonadFree f (EitherT e m) where
-  wrap = EitherT . wrap . fmap runEitherT
-
-instance (Monad f, Traversable f) => Traversable (EitherT e f) where
-  traverse f (EitherT a) =
-    EitherT <$> traverse (either (pure . Left) (fmap Right . f)) a
-  {-# INLINE traverse #-}
-
-instance MonadBase b m => MonadBase b (EitherT e m) where
-  liftBase = liftBaseDefault
-  {-# INLINE liftBase #-}
-
-#if MIN_VERSION_monad_control(1,0,0)
-
-instance MonadTransControl (EitherT e) where
-  type StT (EitherT e) a = Either e a
-  liftWith f = EitherT $ liftM return $ f runEitherT
-  {-# INLINE liftWith #-}
-  restoreT = EitherT
-  {-# INLINE restoreT #-}
-
-instance MonadBaseControl b m => MonadBaseControl b (EitherT e m) where
-  type StM (EitherT e m) a = StM m (StT (EitherT e) a)
-  liftBaseWith = defaultLiftBaseWith
-  {-# INLINE liftBaseWith #-}
-  restoreM     = defaultRestoreM
-  {-# INLINE restoreM #-}
-
-#else
-
-instance MonadTransControl (EitherT e) where
-  newtype StT (EitherT e) a = StEitherT {unStEitherT :: Either e a}
-  liftWith f = EitherT $ liftM return $ f $ liftM StEitherT . runEitherT
-  {-# INLINE liftWith #-}
-  restoreT = EitherT . liftM unStEitherT
-  {-# INLINE restoreT #-}
-
-instance MonadBaseControl b m => MonadBaseControl b (EitherT e m) where
-  newtype StM (EitherT e m) a = StMEitherT { unStMEitherT :: StM m (StT 
(EitherT e) a) }
-  liftBaseWith = defaultLiftBaseWith StMEitherT
-  {-# INLINE liftBaseWith #-}
-  restoreM     = defaultRestoreM unStMEitherT
-  {-# INLINE restoreM #-}
-
-#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/either-4.4.1.1/src/Data/Either/Combinators.hs 
new/either-5/src/Data/Either/Combinators.hs
--- old/either-4.4.1.1/src/Data/Either/Combinators.hs   2016-05-10 
01:31:19.000000000 +0200
+++ new/either-5/src/Data/Either/Combinators.hs 2017-11-21 04:04:46.000000000 
+0100
@@ -1,3 +1,4 @@
+{-# language CPP #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Either.Combinators
@@ -32,11 +33,15 @@
   , unlessRight
   , leftToMaybe
   , rightToMaybe
+  , maybeToLeft
+  , maybeToRight
   , eitherToError
   , swapEither
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative
+#endif
 import Control.Monad.Error.Class ( MonadError(throwError) )
 
 -- ---------------------------------------------------------------------------
@@ -306,6 +311,27 @@
 rightToMaybe :: Either a b -> Maybe b
 rightToMaybe = either (const Nothing) Just
 
+-- | Maybe produce a 'Left', otherwise produce a 'Right'.
+--
+-- >>> maybeToRight "default" (Just 12)
+-- Left 12
+--
+-- >>> maybeToRight "default" Nothing
+-- Right "default"
+maybeToLeft :: b -> Maybe a -> Either a b
+maybeToLeft _ (Just x) = Left x
+maybeToLeft y Nothing  = Right y
+
+-- | Maybe produce a 'Right', otherwise produce a 'Left'.
+--
+-- >>> maybeToRight "default" (Just 12)
+-- Right 12
+--
+-- >>> maybeToRight "default" Nothing
+-- Left "default"
+maybeToRight :: b -> Maybe a -> Either b a
+maybeToRight _ (Just x) = Right x
+maybeToRight y Nothing  = Left y
 
 -- | Generalize @Either e@ as @MonadError e m@.
 --
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/either-4.4.1.1/src/Data/Either/Validation.hs 
new/either-5/src/Data/Either/Validation.hs
--- old/either-4.4.1.1/src/Data/Either/Validation.hs    2016-05-10 
01:31:19.000000000 +0200
+++ new/either-5/src/Data/Either/Validation.hs  2017-11-21 04:04:46.000000000 
+0100
@@ -21,6 +21,8 @@
   , eitherToValidation
   , validationToEither
   , _Validation
+  , vap
+  , ealt
   ) where
 
 import Control.Applicative
@@ -29,6 +31,7 @@
 import Data.Bitraversable(Bitraversable(bitraverse))
 import Data.Foldable (Foldable(foldr))
 import Data.Functor.Alt (Alt((<!>)))
+import Data.Functor.Apply (Apply ((<.>)))
 import Data.Monoid (Monoid(mappend, mempty))
 import Data.Profunctor
 import Data.Semigroup (Semigroup((<>)))
@@ -45,16 +48,20 @@
    fmap _ (Failure e) = Failure e
    fmap f (Success a) = Success (f a)
 
+instance Semigroup e => Apply (Validation e) where
+  Failure e1 <.> Failure e2 = Failure (e1 <> e2)
+  Failure e1 <.> Success _  = Failure e1
+  Success _  <.> Failure e2 = Failure e2
+  Success f  <.> Success a  = Success (f a)
+
 instance Semigroup e => Applicative (Validation e) where
   pure = Success
-  Failure e1 <*> Failure e2 = Failure (e1 <> e2)
-  Failure e1 <*> Success _  = Failure e1
-  Success _  <*> Failure e2 = Failure e2
-  Success f  <*> Success a  = Success (f a)
-
-instance Alt (Validation e) where
-  Failure _ <!> x = x
-  Success a <!> _ = Success a
+  (<*>) = (<.>)
+
+instance Semigroup e => Alt (Validation e) where
+  s@Success{} <!> _ = s
+  _ <!> s@Success{} = s
+  Failure m <!> Failure n = Failure (m <> n)
 
 instance (Semigroup e, Monoid e) => Alternative (Validation e) where
   empty = Failure mempty
@@ -139,3 +146,15 @@
 _Validation :: Iso (Validation e a) (Validation g b) (Either e a) (Either g b)
 _Validation = iso validationToEither eitherToValidation
 {-# INLINE _Validation #-}
+
+vap :: Semigroup m => Either m (a -> b) -> Either m a -> Either m b
+vap (Left m) (Left n) = Left (m <> n)
+vap (Left m) Right{} = Left m
+vap Right{} (Left n) = Left n
+vap (Right f) (Right a) = Right (f a)
+{-# INLINE vap #-}
+
+ealt :: Validation e a -> Validation e a -> Validation e a
+ealt Failure{} r = r
+ealt (Success a) _ = Success a
+{-# INLINE ealt #-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/either-4.4.1.1/tests/Main.hs 
new/either-5/tests/Main.hs
--- old/either-4.4.1.1/tests/Main.hs    1970-01-01 01:00:00.000000000 +0100
+++ new/either-5/tests/Main.hs  2017-11-21 04:04:46.000000000 +0100
@@ -0,0 +1,54 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import           Control.Applicative
+import           Data.Either.Validation
+import           Data.Monoid (Sum(..))
+
+import           Data.Functor (void)
+import           Hedgehog
+import qualified Hedgehog.Gen as Gen
+import qualified Hedgehog.Range as Range
+
+-- -- empty is a neutral element
+-- empty <|> u  =  u
+-- u <|> empty  =  u
+-- -- (<|>) is associative
+-- u <|> (v <|> w)  =  (u <|> v) <|> w
+
+genValidation :: Gen a -> Gen b -> Gen (Validation a b)
+genValidation ga gb = do
+  a <- ga
+  b <- gb
+  Gen.choice [return $ Failure a, return $ Success b]
+
+identity :: (Eq a, Show a) => (a -> a -> a) -> a -> Gen a -> PropertyT IO ()
+identity f i gen = do
+  x <- forAll gen
+  f x i === x
+  f i x === x
+
+assoc :: (Eq a, Show a) => (a -> a -> a) -> Gen a -> PropertyT IO ()
+assoc f gen = do
+  x <- forAll gen
+  y <- forAll gen
+  z <- forAll gen
+
+  let xy = f x y
+      yz = f y z
+
+  f x yz === f xy z
+
+prop_alternative :: Property
+prop_alternative = property $ do
+  let genSumInt = Sum <$> Gen.int (Range.linear 0 maxBound)
+      genVal = genValidation genSumInt genSumInt
+  identity (<|>) empty genVal
+  assoc (<|>) genVal
+
+main :: IO ()
+main =
+  void $ checkParallel $ Group "Test.Either" [
+      ("prop_alternative", prop_alternative)
+    ]


Reply via email to