sdp-0.2: src/SDP/SafePrelude.hs
{-# OPTIONS_HADDOCK ignore-exports #-}
{-# LANGUAGE Safe #-}
{- |
Module : SDP.SafePrelude
Copyright : (c) Andrey Mulik 2019
License : BSD-style
Maintainer : work.a.mulik@gmail.com
Portability : portable
"SDP.SafePrelude" module re-exports common "Prelude" definitions except
those overridden in this library and its extensions (e.g. @sdp-io@).
In addition, this module re-exports the most common definitions from other
@base@ and @sdp@ modules ("Control.Applicative", "Data.Bufunctor",
"SDP.Estimate", etc.) and some useful combinators that were used in this
library and may be useful to its users.
Import "Prelude" without conflicting functions, may require additional
imports for functions overridden in other modules:
@
import Prelude ()
import SDP.SafePrelude
@
-}
module SDP.SafePrelude
(
-- * Exports
module Control.Applicative, liftA4, liftA5, liftA6,
module Control.Monad.IO.Class, stToMIO,
module Control.Monad.ST,
module Control.Monad, liftM6,
module Data.Functor.Classes,
module Data.Bifunctor,
module Data.Foldable,
module SDP.Comparing,
module SDP.Estimate,
module Prelude,
-- * Combinators
on, (?), (?+), (?-), (?^), (?:), (+?), (...), (<=<<), (>>=>), (>>=<<)
)
where
import Prelude hiding
(
-- defined in SDP.Zip and Data.List
zip, zip3, zipWith, zipWith3,
-- defined in SDP.Scan and Data.List
scanl, scanr, scanl1, scanr1,
-- defined in SDP.Linear and Data.List
head, tail, init, last, take, drop, (!!), (++), reverse, filter, lookup,
concat, concatMap, replicate, takeWhile, dropWhile, iterate,
-- defined in System.IO.Handle, System.IO.Classes (@sdp-io@) and System.IO
readFile, writeFile, appendFile, getContents,
getChar, putChar, getLine, putStr, putStrLn
)
import SDP.Comparing
import SDP.Estimate
import Data.Functor.Classes
import Data.Bifunctor
import Data.Foldable hiding ( foldrM, foldlM, concat, concatMap )
import Data.Function ( on )
import Control.Applicative
import Control.Monad.IO.Class
import Control.Monad.ST
import Control.Monad
infixl 8 ?+, ?-
infixr 1 ?, ?^ -- Lowest priority, compatible with infixr 0 $
infixr 0 ...
default ()
--------------------------------------------------------------------------------
{- |
Ternary operator.
> (odd 1 ? "is True" $ "is False") == "is True"
-}
{-# INLINE (?) #-}
(?) :: Bool -> a -> a -> a
(?) = \ p t e -> if p then t else e
-- | @p ?+ f $ a@ returns @'Just' (f a)@ if @(p a)@ and 'Nothing' otherwise.
{-# INLINE (?+) #-}
(?+) :: (a -> Bool) -> (a -> b) -> a -> Maybe b
(?+) = \ p f a -> p a ? Just (f a) $ Nothing
-- | @p ?- f $ a@ returns 'Nothing' if @(p a)@ and @'Just' (f a)@ otherwise.
{-# INLINE (?-) #-}
(?-) :: (a -> Bool) -> (a -> b) -> a -> Maybe b
(?-) = \ p f a -> p a ? Nothing $ Just (f a)
-- | Prepends 'Maybe' to list.
{-# INLINE (?:) #-}
(?:) :: Maybe a -> [a] -> [a]
(?:) = \ mx xs -> case mx of {(Just x) -> x : xs; _ -> xs}
-- | Short version of 'Data.Maybe.fromMaybe'.
{-# INLINE (+?) #-}
(+?) :: a -> Maybe a -> a
_ +? Just x = x
x +? Nothing = x
-- | @(...) = (.) . (.)@.
{-# INLINE (...) #-}
(...) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(...) = (.) . (.)
--------------------------------------------------------------------------------
{-# INLINE (?^) #-}
-- | Lifted @('?')@.
(?^) :: (Monad m) => m Bool -> m a -> m a -> m a
(?^) = \ mb mt me -> do b <- mb; if b then mt else me
-- | Monadic version of @('...')@.
(<=<<) :: (Monad m) => (c -> m d) -> (a -> b -> m c) -> (a -> b -> m d)
(<=<<) = \ mg mf a b -> mf a b >>= mg
-- | Monadic vesion of @('...')@ with reversed arguments.
(>>=>) :: (Monad m) => (a -> b -> m c) -> (c -> m d) -> (a -> b -> m d)
(>>=>) = \ mf mg a b -> mf a b >>= mg
-- | @ma >>=<< mb@ is composition of 'join' and 'liftM2'.
{-# INLINE (>>=<<) #-}
(>>=<<) :: (Monad m) => m a -> m b -> (a -> b -> m c) -> m c
(>>=<<) = \ ma mb f -> join $ liftM2 f ma mb
--------------------------------------------------------------------------------
-- | Very useful combinator.
liftA4 :: (Applicative t) => (a -> b -> c -> d -> e) -> t a -> t b -> t c -> t d -> t e
liftA4 g as bs cs ds = g <$> as <*> bs <*> cs <*> ds
-- | Very very useful combinator
liftA5 :: (Applicative t) => (a -> b -> c -> d -> e -> f) -> t a -> t b -> t c -> t d -> t e -> t f
liftA5 g as bs cs ds es = g <$> as <*> bs <*> cs <*> ds <*> es
-- | An even more useful combinator.
liftA6 :: (Applicative t) => (a -> b -> c -> d -> e -> f -> g) -> t a -> t b -> t c -> t d -> t e -> t f -> t g
liftA6 g as bs cs ds es fs = g <$> as <*> bs <*> cs <*> ds <*> es <*> fs
-- | See 'liftA6'.
liftM6 :: (Monad m) => (a -> b -> c -> d -> e -> f -> g) -> m a -> m b -> m c -> m d -> m e -> m f -> m g
liftM6 g as bs cs ds es fs = do a <- as; b <- bs; c <- cs; d <- ds; e <- es; f <- fs; return $ g a b c d e f
--------------------------------------------------------------------------------
-- | 'stToMIO' is just @'liftIO' . 'stToIO'@.
stToMIO :: (MonadIO io) => ST RealWorld e -> io e
stToMIO = liftIO . stToIO