1
1
mirror of https://github.com/github/semantic.git synced 2024-12-22 22:31:36 +03:00
semantic/src/Prologue.hs
Patrick Thomson 1302fe4ac8 Use -XDerivingVia to clean up our Semigroup/Monoid instances.
Now that we're on GHC 8.6, we can use `-XDerivingVia` in many cases
where we previously had to write instances by hand. If you're not
familiar with `-XDerivingVia`, the [GHC proposal][ghc] is a good place
to start.

[ghc]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0023-deriving-via.rst

Thanks to the `generic-monoid` package, we can derive a `Semigroup`
instance for any product type whose members are `Semigroups`, and the
same goes for `Monoid`. This entails an extra dependency, but it is
better than the `generic-deriving` package, which is way too much overhead.
I've also switched some trivial definitions to newtype-deriving.

Please be aware that this bumps `hlint` and `haskell-src-exts` so that
`hlint` doesn't choke on the `DerivingVia` extension. You'll need to
`stack install hlint` to get it on your `PATH`. Apologies!
2019-01-07 11:23:11 -05:00

82 lines
2.7 KiB
Haskell

{-# LANGUAGE UndecidableInstances #-}
module Prologue
( module X
, eitherA
, foldMapA
, maybeM
, maybeLast
, fromMaybeLast
) where
import Debug.Trace as X (traceShowM, traceM)
import Control.DeepSeq as X
import Data.Bifunctor.Join as X
import Data.Bits as X
import Data.ByteString as X (ByteString)
import Data.Coerce as X
import Data.Functor.Both as X (Both, both, runBothWith)
import Data.IntMap as X (IntMap)
import Data.IntSet as X (IntSet)
import Data.Ix as X (Ix (..))
import Data.List.NonEmpty as X (NonEmpty (..), nonEmpty, some1)
import Data.Map as X (Map)
import Data.Maybe as X
import Data.Monoid (Alt (..))
import Data.Sequence as X (Seq)
import Data.Semilattice.Lower as X (Lower(..))
import Data.Set as X (Set)
import Data.Sum as X (Sum, Element, Elements, (:<), (:<:), Apply (..), inject)
import Data.Text as X (Text)
import Data.These as X
import Control.Exception as X hiding (Handler (..), assert, evaluate, throw, throwIO, throwTo)
-- Typeclasses
import Control.Applicative as X
import Control.Arrow as X ((&&&), (***))
import Control.Monad as X hiding (fail, return)
import Control.Monad.Fail as X (MonadFail (..))
import Control.Monad.IO.Class as X (MonadIO (..))
import Data.Algebra as X
import Data.Bifoldable as X
import Data.Bifunctor as X (Bifunctor (..))
import Data.Bitraversable as X
import Data.Foldable as X hiding (product, sum)
import Data.Function as X (fix, on, (&))
import Data.Functor as X (void, ($>))
import Data.Functor.Classes as X
import Data.Functor.Classes.Generic as X
import Data.Functor.Foldable as X (Base, Corecursive (..), Recursive (..))
import Data.Hashable as X (Hashable, hash, hashUsing, hashWithSalt)
import Data.Hashable.Lifted as X (Hashable1(..), hashWithSalt1)
import Data.Monoid as X (First (..), Last (..), Monoid (..))
import Data.Monoid.Generic as X
import Data.Proxy as X (Proxy (..))
import Data.Semigroup as X (Semigroup (..))
import Data.Traversable as X
import Data.Typeable as X (Typeable)
-- Generics
import GHC.Generics as X (Generic, Generic1)
import GHC.Stack as X
-- | Fold a collection by mapping each element onto an 'Alternative' action.
foldMapA :: (Alternative m, Foldable t) => (b -> m a) -> t b -> m a
foldMapA f = getAlt . foldMap (Alt . f)
maybeLast :: Foldable t => b -> (a -> b) -> t a -> b
maybeLast b f = maybe b f . getLast . foldMap (Last . Just)
fromMaybeLast :: Foldable t => a -> t a -> a
fromMaybeLast b = fromMaybe b . getLast . foldMap (Last . Just)
-- | Extract the 'Just' of a 'Maybe' in an 'Applicative' context or, given 'Nothing', run the provided action.
maybeM :: Applicative f => f a -> Maybe a -> f a
maybeM f = maybe f pure
-- Promote a function to either-applicatives.
eitherA :: Applicative f => (b -> f (Either a c)) -> Either a b -> f (Either a c)
eitherA = either (pure . Left)