graphwiz-1.0.0: common/Prelude.hs
{-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE PatternSynonyms #-}
{- |
Internal module that re-exports the regular prelude, plus some common useful
functions.
-}
module Prelude
( -- * re-exports from useful "default" modules
module P
-- * custom operators
, (...)
-- * maybe helpers
, onNothing
, onNothingM
-- * either helpers
, onLeft
, onLeftM
-- * sequence helpers
, Seq (.., Lone)
-- * hashmap helpers
, unionWithM
, unionWithKeyM
) where
-- re-exports
import Control.Applicative as P (liftA, (<|>))
import Control.Arrow as P (first, left, second, (&&&), (***),
(<<<), (>>>))
import Control.Monad as P
import Control.Monad.Except as P
import Control.Monad.Identity as P
import Control.Monad.Reader as P
import Control.Monad.State.Strict as P
import Control.Monad.Trans.Maybe as P (MaybeT (..))
import Data.Bifunctor as P (bimap)
import Data.Bool as P (bool)
import Data.Char as P (chr, ord)
import Data.Either as P (lefts, partitionEithers, rights)
import Data.Foldable as P (asum, fold, foldMap', foldlM, foldrM,
for_, toList, traverse_)
import Data.Function as P (on, (&))
import Data.Functor as P (($>), (<&>))
import Data.Functor.Const as P (Const (..))
import Data.Hashable as P (Hashable)
import Data.HashMap.Strict as P (HashMap, mapKeys)
import Data.HashSet as P (HashSet)
import Data.List as P (find, findIndex, group, intercalate,
intersect, intersperse, lookup, sort,
sortBy, sortOn, union, unionBy, (\\))
import Data.List.NonEmpty as P (NonEmpty (..), nonEmpty)
import Data.Maybe as P (catMaybes, fromMaybe, isJust, isNothing,
listToMaybe, maybeToList)
import Data.Ord as P (comparing)
import Data.Semigroup as P (Semigroup (..))
import Data.Sequence as P (Seq)
import Data.String as P (IsString)
import Data.Text as P (Text)
import Data.Traversable as P (for)
import Data.Void as P (Void, absurd)
import GHC.Generics as P (Generic)
import "base" Prelude as P hiding (lookup)
-- internal imports
import Data.HashMap.Strict qualified as M
import Data.Sequence (Seq (..))
-- operators
(...) :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)
f ... g = \x y -> f (g x y)
infixr 8 ...
-- maybe helpers
onNothing :: Applicative m => Maybe a -> m a -> m a
onNothing a d = maybe d pure a
onNothingM :: Monad m => m (Maybe a) -> m a -> m a
onNothingM a d = a >>= flip onNothing d
-- either helpers
onLeft :: Applicative m => Either e a -> (e -> m a) -> m a
onLeft a f = either f pure a
onLeftM :: Monad m => m (Either e a) -> (e -> m a) -> m a
onLeftM a f = a >>= flip onLeft f
-- sequence helpers
pattern Lone :: a -> Seq a
pattern Lone x = x :<| Empty
-- hashmap helpers
unionWithM ::
(Monad m, Hashable k) =>
(v -> v -> m v) ->
HashMap k v ->
HashMap k v ->
m (HashMap k v)
unionWithM = unionWithKeyM . const
unionWithKeyM ::
(Monad m, Hashable k) =>
(k -> v -> v -> m v) ->
HashMap k v ->
HashMap k v ->
m (HashMap k v)
unionWithKeyM f m1 m2 = foldM step m1 (M.toList m2)
where
step m (k, new) = case M.lookup k m of
Nothing -> pure $ M.insert k new m
Just old -> do
combined <- f k new old
pure $ M.insert k combined m