summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshersh <>2017-10-11 20:09:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2017-10-11 20:09:00 (GMT)
commita56e2c8ae2612fa24c5f0bd524047f6dfcea1ceb (patch)
tree8d4af41ee38bd9b1cddec5ecbd99408ddda65076
parent0a02f611ad05871f0f0442fd8a5218b65e7e2627 (diff)
version 0.7.0HEAD0.7.0master
-rw-r--r--CHANGES.md21
-rw-r--r--src/Base.hs6
-rw-r--r--src/Bool.hs32
-rw-r--r--src/Containers.hs9
-rw-r--r--src/Exceptions.hs4
-rw-r--r--src/List.hs20
-rw-r--r--src/Monad.hs4
-rw-r--r--src/Monad/Either.hs23
-rw-r--r--src/Monad/Maybe.hs19
-rw-r--r--src/Monad/Trans.hs22
-rw-r--r--src/Universum.hs31
-rw-r--r--universum.cabal2
12 files changed, 126 insertions, 67 deletions
diff --git a/CHANGES.md b/CHANGES.md
index 0624145..4c9ddf9 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,10 +1,27 @@
+0.7.0
+=====
+
+* [#47](https://github.com/serokell/universum/issues/47):
+ Reexport `put` and `get` for `MonadState`.
+* [#48](https://github.com/serokell/universum/issues/48):
+ Export boxed `Vector` type.
+* [#49](https://github.com/serokell/universum/issues/49):
+ Export `IdentityT` and `runIdentityT`.
+* [#51](https://github.com/serokell/universum/issues/51):
+ Add `fromRight` and `fromLeft` that behave like `fromMaybe` but for `Either`.
+* [#52](https://github.com/serokell/universum/issues/52):
+ Add `maybeToMonoid :: Monoid m => Maybe m -> m`.
+* Remove `Symbol`-related types for sure.
+* Return back seems to be useful function `guardM` removed in `v0.3`.
+* Add `notElem` for `NonTrivialContainer`.
+
0.6.1
=====
* Fixed version number bug (it had 4 numbers).
0.6.0.0
-=====
+=======
* [#62](https://github.com/serokell/universum/issues/62):
Export exceptions-related functions from 'safe-exceptions'.
@@ -15,7 +32,7 @@
* Fix an infinite loop in `decodeUtf8` from `Text` to `ByteString.Lazy`.
0.5
-=====
+===
* Export `MonadTrans` typeclass.
* Remove `Symbol`-related exports from `GHC.TypeLits`.
diff --git a/src/Base.hs b/src/Base.hs
index e902cb8..a8d4094 100644
--- a/src/Base.hs
+++ b/src/Base.hs
@@ -37,9 +37,9 @@ import GHC.Float (Double (..), Float (..), Floating (..), s
import GHC.Num (Integer, Num (..), subtract)
import GHC.Real hiding ((%))
import GHC.Show (Show (..))
-import GHC.TypeLits (CmpNat, KnownNat, KnownSymbol, Nat, SomeNat (..),
- SomeSymbol (..), Symbol, natVal, someNatVal,
- someSymbolVal, symbolVal)
+import GHC.TypeLits (CmpNat, KnownNat, Nat, SomeNat (..), natVal,
+ someNatVal)
+
import GHC.Types (Bool, Char, Coercible, IO, Int, Ordering, Word)
diff --git a/src/Bool.hs b/src/Bool.hs
index d447c58..86762fe 100644
--- a/src/Bool.hs
+++ b/src/Bool.hs
@@ -1,15 +1,20 @@
{-# LANGUAGE Safe #-}
--- | Convenient commonly used and very helpful functions to work with 'Bool'.
+-- | Convenient commonly used and very helpful functions to work with
+-- 'Bool' and also with monads.
module Bool
- ( whenM
- , unlessM
+ ( bool
+ , guard
+ , guardM
, ifM
- , bool
+ , unless
+ , unlessM
+ , when
+ , whenM
) where
-import Control.Monad (Monad, unless, when, (>>=))
+import Control.Monad (Monad, MonadPlus, guard, unless, when, (>>=))
import Data.Bool (Bool)
import Data.Function (flip)
@@ -52,8 +57,19 @@ unlessM p m = p >>= flip unless m
-- True text
ifM :: Monad m => m Bool -> m a -> m a -> m a
ifM p x y = p >>= \b -> if b then x else y
+{-# INLINE ifM #-}
-{-
+-- | Monadic version of 'guard'. Occasionally useful.
+-- Here some complex but real-life example:
+-- @
+-- findSomePath :: IO (Maybe FilePath)
+--
+-- somePath :: MaybeT IO FilePath
+-- somePath = do
+-- path <- MaybeT findSomePath
+-- guardM $ liftIO $ doesDirectoryExist path
+-- return path
+-- @
guardM :: MonadPlus m => m Bool -> m ()
-guardM f = guard =<< f
--}
+guardM f = f >>= guard
+{-# INLINE guardM #-}
diff --git a/src/Containers.hs b/src/Containers.hs
index 066bb58..8d2423d 100644
--- a/src/Containers.hs
+++ b/src/Containers.hs
@@ -206,6 +206,9 @@ class Container t => NontrivialContainer t where
elem :: Eq (Element t) => Element t -> t -> Bool
+ notElem :: Eq (Element t) => Element t -> t -> Bool
+ notElem x = not . elem x
+
maximum :: Ord (Element t) => t -> Element t
minimum :: Ord (Element t) => t -> Element t
@@ -247,6 +250,8 @@ instance {-# OVERLAPPABLE #-} Foldable f => NontrivialContainer (f a) where
{-# INLINE length #-}
elem = F.elem
{-# INLINE elem #-}
+ notElem = F.notElem
+ {-# INLINE notElem #-}
maximum = F.maximum
{-# INLINE maximum #-}
minimum = F.minimum
@@ -334,6 +339,8 @@ instance NontrivialContainer BS.ByteString where
{-# INLINE length #-}
elem = BS.elem
{-# INLINE elem #-}
+ notElem = BS.notElem
+ {-# INLINE notElem #-}
maximum = BS.maximum
{-# INLINE maximum #-}
minimum = BS.minimum
@@ -362,6 +369,8 @@ instance NontrivialContainer BSL.ByteString where
{-# INLINE length #-}
elem = BSL.elem
{-# INLINE elem #-}
+ notElem = BSL.notElem
+ {-# INLINE notElem #-}
maximum = BSL.maximum
{-# INLINE maximum #-}
minimum = BSL.minimum
diff --git a/src/Exceptions.hs b/src/Exceptions.hs
index 49bb114..c28151c 100644
--- a/src/Exceptions.hs
+++ b/src/Exceptions.hs
@@ -11,10 +11,12 @@ module Exceptions
, note
) where
-import Control.Applicative (Applicative (pure))
+-- exceptions from safe-exceptions
import Control.Exception.Safe (Exception, MonadCatch, MonadMask (..),
MonadThrow, SomeException (..), bracket,
bracket_, catch, catchAny, finally, throwM)
+
+import Control.Applicative (Applicative (pure))
import Control.Monad.Except (MonadError, throwError)
import Data.Maybe (Maybe, maybe)
diff --git a/src/List.hs b/src/List.hs
index 08ca925..fe24048 100644
--- a/src/List.hs
+++ b/src/List.hs
@@ -4,27 +4,31 @@
-- | Utility functions to work with lists.
module List
- ( list
+ ( module Data.List
+
+ , list
, hashNub
, ordNub
- , sortBy
- , sortOn
, sortWith
- , unzip
- , unzip3
#if ( __GLASGOW_HASKELL__ >= 800 )
, whenNotNull
, whenNotNullM
#endif
- , zip
- , zip3
) where
+import Data.List (break, cycle, drop, dropWhile, filter, genericDrop,
+ genericLength, genericReplicate, genericSplitAt,
+ genericTake, group, inits, intercalate, intersperse,
+ isPrefixOf, iterate, permutations, repeat,
+ replicate, reverse, scanl, scanr, sort, sortBy,
+ sortBy, sortOn, splitAt, subsequences, tails, take,
+ takeWhile, transpose, unfoldr, unzip, unzip3, zip,
+ zip3, zipWith)
+
import Data.Eq (Eq)
import Data.Functor (fmap)
import Data.Hashable (Hashable)
import Data.HashSet as HS
-import Data.List (sortBy, sortOn, unzip, unzip3, zip, zip3)
import Data.Ord (Ord)
import qualified Data.Set as Set
import GHC.Exts (sortWith)
diff --git a/src/Monad.hs b/src/Monad.hs
index 685e9b0..150baae 100644
--- a/src/Monad.hs
+++ b/src/Monad.hs
@@ -32,10 +32,6 @@ module Monad
, concatMapM
, concatForM
- , guard
- , when
- , unless
-
, allM
, anyM
, andM
diff --git a/src/Monad/Either.hs b/src/Monad/Either.hs
index 5599b2d..6df7d3d 100644
--- a/src/Monad/Either.hs
+++ b/src/Monad/Either.hs
@@ -4,6 +4,8 @@
module Monad.Either
( module Data.Either
+ , fromLeft
+ , fromRight
, maybeToLeft
, maybeToRight
, leftToMaybe
@@ -23,6 +25,27 @@ import Data.Maybe (Maybe (..), maybe)
import Applicative (pass)
+
+-- | Extracts value from 'Left' or return given default value.
+--
+-- >>> fromLeft 0 (Left 3)
+-- 3
+-- >>> fromLeft 0 (Right 5)
+-- 0
+fromLeft :: a -> Either a b -> a
+fromLeft _ (Left a) = a
+fromLeft a (Right _) = a
+
+-- | Extracts value from 'Right' or return given default value.
+--
+-- >>> fromRight 0 (Left 3)
+-- 0
+-- >>> fromRight 0 (Right 5)
+-- 5
+fromRight :: b -> Either a b -> b
+fromRight b (Left _) = b
+fromRight _ (Right b) = b
+
-- | Maps left part of 'Either' to 'Maybe'.
--
-- >>> leftToMaybe (Left True)
diff --git a/src/Monad/Maybe.hs b/src/Monad/Maybe.hs
index f1cdc40..3770919 100644
--- a/src/Monad/Maybe.hs
+++ b/src/Monad/Maybe.hs
@@ -3,7 +3,10 @@
-- | Utility functions to work with 'Data.Maybe' data type as monad.
module Monad.Maybe
- ( whenJust
+ ( module Data.Maybe
+
+ , maybeToMonoid
+ , whenJust
, whenJustM
, whenNothing
, whenNothing_
@@ -11,12 +14,24 @@ module Monad.Maybe
, whenNothingM_
) where
+import Data.Maybe (Maybe (..), catMaybes, fromMaybe, isJust, isNothing,
+ mapMaybe, maybe, maybeToList)
+
import Control.Applicative (Applicative, pure)
import Control.Monad (Monad (..))
-import Data.Maybe (Maybe (..))
+import Data.Monoid (Monoid (mempty))
import Applicative (pass)
+-- | Extracts 'Monoid' value from 'Maybe' returning 'mempty' if 'Nothing'.
+--
+-- >>> maybeToMonoid (Just [1,2,3] :: Maybe [Int])
+-- [1,2,3]
+-- >>> maybeToMonoid (Nothing :: Maybe [Int])
+-- []
+maybeToMonoid :: Monoid m => Maybe m -> m
+maybeToMonoid = fromMaybe mempty
+
-- | Specialized version of 'for_' for 'Maybe'. It's used for code readability.
-- Also helps to avoid space leaks:
-- <http://www.snoyman.com/blog/2017/01/foldable-mapm-maybe-and-recursive-functions Foldable.mapM_ space leak>.
diff --git a/src/Monad/Trans.hs b/src/Monad/Trans.hs
index d04845b..e2e8715 100644
--- a/src/Monad/Trans.hs
+++ b/src/Monad/Trans.hs
@@ -8,6 +8,7 @@ module Monad.Trans
, module Control.Monad.Reader
, module Control.Monad.State.Strict
, module Control.Monad.Trans
+ , module Control.Monad.Trans.Identity
, module Control.Monad.Trans.Maybe
-- * Convenient functions to work with 'Reader' monad
@@ -24,16 +25,19 @@ module Monad.Trans
) where
-- Monad transformers
-import Control.Monad.Except (ExceptT (..), runExceptT)
-import Control.Monad.Reader (MonadReader, Reader, ReaderT (..), ask, asks,
- local, reader, runReader)
-import Control.Monad.State.Strict (MonadState, State, StateT (..), evalState,
- evalStateT, execState, execStateT, gets,
- modify, runState, state, withState)
-import Control.Monad.Trans (MonadIO, MonadTrans, lift, liftIO)
-import Control.Monad.Trans.Maybe (MaybeT (..), exceptToMaybeT, maybeToExceptT)
+import Control.Monad.Except (ExceptT (..), runExceptT)
+import Control.Monad.Reader (MonadReader, Reader, ReaderT (..), ask,
+ asks, local, reader, runReader)
+import Control.Monad.State.Strict (MonadState, State, StateT (..), evalState,
+ evalStateT, execState, execStateT, get,
+ gets, modify, put, runState, state,
+ withState)
+import Control.Monad.Trans (MonadIO, MonadTrans, lift, liftIO)
+import Control.Monad.Trans.Identity (IdentityT (runIdentityT))
+import Control.Monad.Trans.Maybe (MaybeT (..), exceptToMaybeT,
+ maybeToExceptT)
-import Prelude (Functor, flip, fst, snd, (<$>))
+import Prelude (Functor, flip, fst, snd, (<$>))
-- | Shorter and more readable alias for @flip runReaderT@.
usingReaderT :: r -> ReaderT r m a -> m a
diff --git a/src/Universum.hs b/src/Universum.hs
index e4b25de..683a065 100644
--- a/src/Universum.hs
+++ b/src/Universum.hs
@@ -26,7 +26,6 @@ module Universum
, evaluateNF_
, evaluateWHNF
, evaluateWHNF_
- , guarded
, identity
, map
, pretty
@@ -107,19 +106,11 @@ import Data.HashMap.Strict as X (HashMap)
import Data.HashSet as X (HashSet)
import Data.IntMap.Strict as X (IntMap)
import Data.IntSet as X (IntSet)
-import Data.List as X (break, cycle, drop, dropWhile, filter,
- genericDrop, genericLength,
- genericReplicate, genericSplitAt,
- genericTake, group, inits, intercalate,
- intersperse, isPrefixOf, iterate,
- permutations, repeat, replicate, reverse,
- scanl, scanr, sort, sortBy, splitAt,
- subsequences, tails, take, takeWhile,
- transpose, unfoldr, zip, zipWith)
import Data.Map.Strict as X (Map)
import Data.Sequence as X (Seq)
import Data.Set as X (Set)
import Data.Tuple as X (curry, fst, snd, swap, uncurry)
+import Data.Vector as X (Vector)
#if ( __GLASGOW_HASKELL__ >= 710 )
import Data.Proxy as X (Proxy (..))
@@ -132,19 +123,13 @@ import Data.Bits as X (xor)
import Data.Bool as X (Bool (..), not, otherwise, (&&), (||))
import Data.Char as X (chr)
import Data.Int as X (Int, Int16, Int32, Int64, Int8)
-import Data.Maybe as X (Maybe (..), catMaybes, fromMaybe, isJust,
- isNothing, mapMaybe, maybe, maybeToList)
import Data.Word as X (Word, Word16, Word32, Word64, Word8,
byteSwap16, byteSwap32, byteSwap64)
import Data.Function as X (const, fix, flip, on, ($), (.))
--- Generics and type level magic
+-- Generics
import GHC.Generics as X (Generic)
-#if ( __GLASGOW_HASKELL__ >= 710 )
-import GHC.TypeLits as X (CmpNat, KnownNat, KnownSymbol, Nat,
- SomeNat (..), natVal, someNatVal)
-#endif
-- Buildable
import Data.Text.Buildable (Buildable (build))
@@ -228,18 +213,6 @@ print = liftIO . Prelude.print
readEither :: (ToString a, Read b) => a -> Either Text b
readEither = X.first toText . Text.Read.readEither . X.toString
--- | Version of 'Prelude.guard' that takes verification function.
--- Can be used in some similar way:
--- @
--- safeSum :: Int -> Int -> Maybe Int
--- safeSum a b = do
--- verifiedA <- guarded (>0) a
--- verifiedB <- guarded (>0) b
--- pure $ verifiedA + verifiedB
--- @
-guarded :: (Alternative f) => (a -> Bool) -> a -> f a
-guarded p x = X.bool empty (pure x) (p x)
-
-- | Generalized version of 'Prelude.show'.
show :: (Show a, IsString b) => a -> b
show x = X.fromString (PBase.show x)
diff --git a/universum.cabal b/universum.cabal
index 823af48..a4ae174 100644
--- a/universum.cabal
+++ b/universum.cabal
@@ -1,5 +1,5 @@
name: universum
-version: 0.6.1
+version: 0.7.0
synopsis: Custom prelude used in Serokell
description: Custom prelude used in Serokell
homepage: https://github.com/serokell/universum