bytestring-trie-0.2.7.6: dev/Shared/BaseCompat.hs
{-# OPTIONS_GHC -Wall -fwarn-tabs #-}
{-# LANGUAGE CPP #-}
----------------------------------------------------------------
-- ~ 2022.03.12
-- |
-- Module : Shared.BaseCompat
-- Copyright : 2008--2023 wren romano
-- License : BSD-3-Clause
-- Maintainer : wren@cpan.org
-- Stability : provisional
-- Portability : portable (CPP)
--
-- Compatibility shim for various versions of @base@.
--
-- TODO: depending how much more we need in here, consider instead
-- just using the @base-compat-batteries@ package instead.
----------------------------------------------------------------
module Shared.BaseCompat
(
-- * "Data.Semigroup"
(<>)
, Sum(..)
, Product(..)
-- TODO: (?) 'Min', 'Max', 'Endo', 'Data.Monoid.Dual'
-- * "Data.Functor"
, (<&>)
-- * "Data.Functor.Compose"
, Compose(..)
-- * "Data.Functor.Identity"
, Identity(..)
) where
----------------------------------------------------------------
#if MIN_VERSION_base(4,13,0)
-- [GHC 8.8.1]: @(<&>)@ added to "Data.Functor".
import Data.Functor ((<&>))
#endif
----------------------------------------------------------------
#if MIN_VERSION_base(4,13,0)
-- [GHC 8.8.1]: Prelude re-exports 'Semigroup' and @('<>')@, but not 'stimes'.
#elif MIN_VERSION_base(4,9,0)
-- [GHC 8.0.1]: "Data.Semigroup" added to base.
import Data.Semigroup (Semigroup((<>)))
#elif MIN_VERSION_base(4,5,0)
-- [GHC 7.4.1]: @(<>)@ added to "Data.Monoid".
import Data.Monoid ((<>))
#endif
----------------------------------------------------------------
-- For [base 4.13 / GHC 8.8.1], this module needs to explicitly
-- import 'Sum' in order to re-export it. However, for some reason
-- those versions will also cause users of this module to get an
-- \"unused import\" warning, even though the Prelude doesn't export
-- 'Data.Semigroup.Sum'.
-- TODO: figure out what the heck is going on re that warning...
-- FIXME: now getting that issue for GHC 8.0--8.6 too...
#if MIN_VERSION_base(4,9,0)
-- [GHC 8.0.1]
import Data.Semigroup (Sum(..), Product(..))
import Data.Functor.Compose (Compose(..))
#endif
#if MIN_VERSION_base(4,8,0)
-- [GHC 7.10.1]
import Data.Functor.Identity (Identity(..))
#endif
#if MIN_VERSION_base(4,7,0) && !(MIN_VERSION_base(4,9,0))
-- [GHC 7.8.1]: "Data.Coerce" added to base.
import Data.Coerce (coerce)
#endif
----------------------------------------------------------------
----------------------------------------------------------------
#if !(MIN_VERSION_base(4,13,0))
(<&>) :: Functor f => f a -> (a -> b) -> f b
(<&>) = flip fmap
{-# INLINE (<&>) #-}
#endif
----------------------------------------------------------------
#if !(MIN_VERSION_base(4,9,0))
-- | Same as the derived instance, if the type was declared without
-- the record\/field syntax.
newtypeShowsPrec :: Show a => String -> (b -> a) -> Int -> b -> ShowS
newtypeShowsPrec name oldtype d x =
showParen (d > 10)
$ showString name
. showChar ' '
. showsPrec 11 (oldtype x)
-- aka:
-- > newtypeShowsPrec name oldtype =
-- > Data.Functor.Classes.showsUnaryWith (\d -> showsPrec d . oldtype) name
-- But that function was also introduced in base-4.9.0.0
#endif
----------------------------------------------------------------
#if !(MIN_VERSION_base(4,9,0))
newtype Sum a = Sum { getSum :: a }
deriving (Eq, Ord, Bounded, Num)
-- We're not deriving the 'Show' instance, even though base does.
-- Also forgoing the 'Read' instance.
instance (Show a) => Show (Sum a) where
showsPrec = newtypeShowsPrec "Sum" getSum
instance Num a => Monoid (Sum a) where
mempty = Sum 0
# if MIN_VERSION_base(4,7,0)
mappend = coerce ((+) :: a -> a -> a)
# else
mappend (Sum x) (Sum y) = Sum (x + y)
# endif
-- TODO: if needed, there are also instances for: Functor, Applicative, Monad.
#endif
----------------------------------------------------------------
#if !(MIN_VERSION_base(4,9,0))
newtype Product a = Product { getProduct :: a }
deriving (Eq, Ord, Bounded, Num)
-- We're not deriving the 'Show' instances, even though base does.
-- Also forgoing the 'Read' instance.
instance (Show a) => Show (Product a) where
showsPrec = newtypeShowsPrec "Product" getProduct
instance Num a => Monoid (Product a) where
mempty = Product 1
# if MIN_VERSION_base(4,7,0)
mappend = coerce ((*) :: a -> a -> a)
# else
mappend (Product x) (Product y) = Product (x * y)
# endif
-- TODO: if needed, there are also instances for: Functor, Applicative, Monad.
#endif
----------------------------------------------------------------
#if !(MIN_VERSION_base(4,9,0))
newtype Compose f g a = Compose { getCompose :: f (g a) }
-- Ignoring the other instances since we don't need them.
-- BUG: can't define 'Show' instance without 'Show1' for @f,g@; but
-- 'Show1' wasn't introduced until base-4.9.0.0. Ditto for 'Eq',
-- 'Ord'.
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = Compose (fmap (fmap f) x)
# if __GLASGOW_HASKELL__
a <$ Compose x = Compose (fmap (a <$) x)
# endif
instance (Foldable f, Foldable g) => Foldable (Compose f g) where
foldMap f (Compose t) = foldMap (foldMap f) t
instance (Traversable f, Traversable g) => Traversable (Compose f g) where
traverse f (Compose t) = Compose <$> traverse (traverse f) t
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
pure x = Compose (pure (pure x))
Compose f <*> Compose x = Compose (liftA2 (<*>) f x)
#endif
----------------------------------------------------------------
#if !(MIN_VERSION_base(4,8,0))
newtype Identity a = Identity { runIdentity :: a }
deriving (Eq, Ord, Bounded, Num)
-- Ignoring the other instances since we don't need them.
instance (Show a) => Show (Identity a) where
showsPrec = newtypeShowsPrec "Identity" runIdentity
instance Functor Identity where
# if MIN_VERSION_base(4,7,0)
fmap = coerce
# else
fmap f (Identity x) = Identity (f x)
# endif
instance Applicative Identity where
pure = Identity
# if MIN_VERSION_base(4,7,0)
(<*>) = coerce
# else
Identity f <*> Identity x = Identity (f x)
# endif
-- Using 'runIdentity' here instead of pattern matching, because
-- that's what base-4.16.0.0 does.
instance Monad Identity where
m >>= k = k (runIdentity m)
-- TODO: if needed, there's also a Foldable instance.
#endif
----------------------------------------------------------------
----------------------------------------------------------- fin.