{-# 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