universum 0.9.2 → 1.0.0
raw patch · 67 files changed
+2810/−2697 lines, 67 filesdep −exceptionsdep −safedep ~basePVP ok
version bump matches the API change (PVP)
Dependencies removed: exceptions, safe
Dependency ranges changed: base
API changes (from Hackage documentation)
- Applicative: pass :: Applicative f => f ()
- Base: ($!) :: (a -> b) -> a -> b
- Base: infixr 0 $!
- Bool: bool :: a -> a -> Bool -> a
- Bool: guard :: Alternative f => Bool -> f ()
- Bool: guardM :: MonadPlus m => m Bool -> m ()
- Bool: ifM :: Monad m => m Bool -> m a -> m a -> m a
- Bool: unless :: Applicative f => Bool -> f () -> f ()
- Bool: unlessM :: Monad m => m Bool -> m () -> m ()
- Bool: when :: Applicative f => Bool -> f () -> f ()
- Bool: whenM :: Monad m => m Bool -> m () -> m ()
- Container.Class: WrappedList :: (f a) -> WrappedList f a
- Container.Class: all :: Container t => (Element t -> Bool) -> t -> Bool
- Container.Class: and :: (Container t, (Element t ~ Bool)) => t -> Bool
- Container.Class: any :: Container t => (Element t -> Bool) -> t -> Bool
- Container.Class: asum :: (Container t, Alternative f, Element t ~ f a) => t -> f a
- Container.Class: class ToList t => Container t
- Container.Class: class One x where {
- Container.Class: class ToList t
- Container.Class: elem :: (Container t, Eq (Element t)) => Element t -> t -> Bool
- Container.Class: find :: Container t => (Element t -> Bool) -> t -> Maybe (Element t)
- Container.Class: fold :: (Container t, Monoid (Element t)) => t -> Element t
- Container.Class: foldMap :: (Container t, Monoid m) => (Element t -> m) -> t -> m
- Container.Class: foldl :: Container t => (b -> Element t -> b) -> b -> t -> b
- Container.Class: foldl' :: Container t => (b -> Element t -> b) -> b -> t -> b
- Container.Class: foldl1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t
- Container.Class: foldr :: Container t => (Element t -> b -> b) -> b -> t -> b
- Container.Class: foldr' :: Container t => (Element t -> b -> b) -> b -> t -> b
- Container.Class: foldr1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t
- Container.Class: forM_ :: (Container t, Monad m) => t -> (Element t -> m b) -> m ()
- Container.Class: for_ :: (Container t, Applicative f) => t -> (Element t -> f b) -> f ()
- Container.Class: head :: Container t => t -> Maybe (Element t)
- Container.Class: instance (TypeError ...) => Container.Class.Container (Data.Either.Either a b)
- Container.Class: instance (TypeError ...) => Container.Class.Container (Data.Functor.Identity.Identity a)
- Container.Class: instance (TypeError ...) => Container.Class.Container (GHC.Base.Maybe a)
- Container.Class: instance (TypeError ...) => Container.Class.Container (a, b)
- Container.Class: instance (TypeError ...) => Container.Class.ToList (a, b)
- Container.Class: instance Container.Class.Container Data.ByteString.Internal.ByteString
- Container.Class: instance Container.Class.Container Data.ByteString.Lazy.Internal.ByteString
- Container.Class: instance Container.Class.Container Data.IntSet.Internal.IntSet
- Container.Class: instance Container.Class.Container Data.Text.Internal.Lazy.Text
- Container.Class: instance Container.Class.Container Data.Text.Internal.Text
- Container.Class: instance Container.Class.One (Data.IntMap.Internal.IntMap v)
- Container.Class: instance Container.Class.One (Data.List.NonEmpty.NonEmpty a)
- Container.Class: instance Container.Class.One (Data.Map.Internal.Map k v)
- Container.Class: instance Container.Class.One (Data.Sequence.Internal.Seq a)
- Container.Class: instance Container.Class.One (Data.Set.Internal.Set v)
- Container.Class: instance Container.Class.One (Data.Vector.Vector a)
- Container.Class: instance Container.Class.One Data.ByteString.Internal.ByteString
- Container.Class: instance Container.Class.One Data.ByteString.Lazy.Internal.ByteString
- Container.Class: instance Container.Class.One Data.IntSet.Internal.IntSet
- Container.Class: instance Container.Class.One Data.Text.Internal.Lazy.Text
- Container.Class: instance Container.Class.One Data.Text.Internal.Text
- Container.Class: instance Container.Class.One [a]
- Container.Class: instance Container.Class.ToList (f a) => Container.Class.Container (Container.Class.WrappedList f a)
- Container.Class: instance Container.Class.ToList (f a) => Container.Class.ToList (Container.Class.WrappedList f a)
- Container.Class: instance Container.Class.ToList Data.ByteString.Internal.ByteString
- Container.Class: instance Container.Class.ToList Data.ByteString.Lazy.Internal.ByteString
- Container.Class: instance Container.Class.ToList Data.IntSet.Internal.IntSet
- Container.Class: instance Container.Class.ToList Data.Text.Internal.Lazy.Text
- Container.Class: instance Container.Class.ToList Data.Text.Internal.Text
- Container.Class: instance Data.Foldable.Foldable f => Container.Class.Container (f a)
- Container.Class: instance Data.Foldable.Foldable f => Container.Class.ToList (f a)
- Container.Class: instance Data.Hashable.Class.Hashable k => Container.Class.One (Data.HashMap.Base.HashMap k v)
- Container.Class: instance Data.Hashable.Class.Hashable v => Container.Class.One (Data.HashSet.HashSet v)
- Container.Class: instance Data.Primitive.Types.Prim a => Container.Class.One (Data.Vector.Primitive.Vector a)
- Container.Class: instance Data.Vector.Unboxed.Base.Unbox a => Container.Class.One (Data.Vector.Unboxed.Base.Vector a)
- Container.Class: instance Foreign.Storable.Storable a => Container.Class.One (Data.Vector.Storable.Vector a)
- Container.Class: length :: Container t => t -> Int
- Container.Class: mapM_ :: (Container t, Monad m) => (Element t -> m b) -> t -> m ()
- Container.Class: maximum :: (Container t, Ord (Element t)) => t -> Element t
- Container.Class: minimum :: (Container t, Ord (Element t)) => t -> Element t
- Container.Class: newtype WrappedList f a
- Container.Class: notElem :: (Container t, Eq (Element t)) => Element t -> t -> Bool
- Container.Class: null :: ToList t => t -> Bool
- Container.Class: one :: One x => OneItem x -> x
- Container.Class: or :: (Container t, (Element t ~ Bool)) => t -> Bool
- Container.Class: product :: (Container t, Num (Element t)) => t -> Element t
- Container.Class: sequenceA_ :: (Container t, Applicative f, Element t ~ f a) => t -> f ()
- Container.Class: sequence_ :: (Container t, Monad m, Element t ~ m a) => t -> m ()
- Container.Class: sum :: (Container t, Num (Element t)) => t -> Element t
- Container.Class: toList :: ToList t => t -> [Element t]
- Container.Class: traverse_ :: (Container t, Applicative f) => (Element t -> f b) -> t -> f ()
- Container.Class: type NontrivialContainer t = Container t
- Container.Class: type family OneItem x;
- Container.Class: }
- Debug: Undefined :: Undefined
- Debug: data Undefined
- Debug: error :: Text -> a
- Debug: instance Data.Data.Data Debug.Undefined
- Debug: instance GHC.Classes.Eq Debug.Undefined
- Debug: instance GHC.Classes.Ord Debug.Undefined
- Debug: instance GHC.Enum.Bounded Debug.Undefined
- Debug: instance GHC.Enum.Enum Debug.Undefined
- Debug: instance GHC.Generics.Generic Debug.Undefined
- Debug: instance GHC.Read.Read Debug.Undefined
- Debug: instance GHC.Show.Show Debug.Undefined
- Debug: trace :: Print b => b -> a -> a
- Debug: traceId :: Text -> Text
- Debug: traceM :: (Monad m) => Text -> m ()
- Debug: traceShow :: Show a => a -> b -> b
- Debug: traceShowId :: Show a => a -> a
- Debug: traceShowM :: (Show a, Monad m) => a -> m ()
- Debug: undefined :: a
- Exceptions: Bug :: SomeException -> CallStack -> Bug
- Exceptions: bug :: (HasCallStack, Exception e) => e -> a
- Exceptions: data Bug
- Exceptions: instance GHC.Exception.Exception Exceptions.Bug
- Exceptions: instance GHC.Show.Show Exceptions.Bug
- Exceptions: note :: (MonadError e m) => e -> Maybe a -> m a
- Functor: ($>) :: Functor f => f a -> b -> f b
- Functor: (<$) :: Functor f => a -> f b -> f a
- Functor: (<$>) :: Functor f => (a -> b) -> f a -> f b
- Functor: (<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
- Functor: class Functor (f :: * -> *)
- Functor: fmap :: Functor f => (a -> b) -> f a -> f b
- Functor: infixl 4 <<$>>
- Functor: void :: Functor f => f a -> f ()
- Lifted: stToIO :: MonadIO m => ST RealWorld a -> m a
- Lifted.Concurrent: atomically :: MonadIO m => STM a -> m a
- Lifted.Concurrent: data MVar a :: * -> *
- Lifted.Concurrent: data STM a :: * -> *
- Lifted.Concurrent: data TVar a :: * -> *
- Lifted.Concurrent: modifyTVar' :: () => TVar a -> (a -> a) -> STM ()
- Lifted.Concurrent: newEmptyMVar :: MonadIO m => m (MVar a)
- Lifted.Concurrent: newMVar :: MonadIO m => a -> m (MVar a)
- Lifted.Concurrent: newTVar :: () => a -> STM TVar a
- Lifted.Concurrent: newTVarIO :: MonadIO m => a -> m (TVar a)
- Lifted.Concurrent: putMVar :: MonadIO m => MVar a -> a -> m ()
- Lifted.Concurrent: readMVar :: MonadIO m => MVar a -> m a
- Lifted.Concurrent: readTVar :: () => TVar a -> STM a
- Lifted.Concurrent: readTVarIO :: MonadIO m => TVar a -> m a
- Lifted.Concurrent: swapMVar :: MonadIO m => MVar a -> a -> m a
- Lifted.Concurrent: takeMVar :: MonadIO m => MVar a -> m a
- Lifted.Concurrent: tryPutMVar :: MonadIO m => MVar a -> a -> m Bool
- Lifted.Concurrent: tryReadMVar :: MonadIO m => MVar a -> m (Maybe a)
- Lifted.Concurrent: tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a)
- Lifted.Concurrent: writeTVar :: () => TVar a -> a -> STM ()
- Lifted.Env: die :: MonadIO m => String -> m ()
- Lifted.Env: exitFailure :: MonadIO m => m a
- Lifted.Env: exitSuccess :: MonadIO m => m a
- Lifted.Env: exitWith :: MonadIO m => ExitCode -> m a
- Lifted.Env: getArgs :: MonadIO m => m [String]
- Lifted.File: appendFile :: MonadIO m => FilePath -> Text -> m ()
- Lifted.File: getContents :: MonadIO m => m Text
- Lifted.File: getLine :: MonadIO m => m Text
- Lifted.File: interact :: MonadIO m => (Text -> Text) -> m ()
- Lifted.File: openFile :: MonadIO m => FilePath -> IOMode -> m Handle
- Lifted.File: readFile :: MonadIO m => FilePath -> m Text
- Lifted.File: writeFile :: MonadIO m => FilePath -> Text -> m ()
- Lifted.IORef: atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
- Lifted.IORef: atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
- Lifted.IORef: atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()
- Lifted.IORef: data IORef a :: * -> *
- Lifted.IORef: modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()
- Lifted.IORef: modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()
- Lifted.IORef: newIORef :: MonadIO m => a -> m (IORef a)
- Lifted.IORef: readIORef :: MonadIO m => IORef a -> m a
- Lifted.IORef: writeIORef :: MonadIO m => IORef a -> a -> m ()
- List: list :: [b] -> (a -> b) -> [a] -> [b]
- List: sortWith :: Ord b => (a -> b) -> [a] -> [a]
- List: whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()
- List: whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m ()
- Monad: (<$!>) :: Monad m => (a -> b) -> m a -> m b
- Monad: (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
- Monad: (=<<) :: Monad m => (a -> m b) -> m a -> m b
- Monad: (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
- Monad: (>>) :: Monad m => m a -> m b -> m b
- Monad: (>>=) :: Monad m => m a -> (a -> m b) -> m b
- Monad: allM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool
- Monad: andM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool
- Monad: anyM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool
- Monad: ap :: Monad m => m (a -> b) -> m a -> m b
- Monad: class Applicative m => Monad (m :: * -> *)
- Monad: class Monad m => MonadFail (m :: * -> *)
- Monad: class (Alternative m, Monad m) => MonadPlus (m :: * -> *)
- Monad: concatForM :: (Applicative f, Monoid m, Container (l m), Traversable l) => l a -> (a -> f m) -> f m
- Monad: concatMapM :: (Applicative f, Monoid m, Container (l m), Traversable l) => (a -> f m) -> l a -> f m
- Monad: fail :: MonadFail m => String -> m a
- Monad: filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]
- Monad: foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
- Monad: foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m ()
- Monad: forever :: Applicative f => f a -> f b
- Monad: infixr 1 <=<
- Monad: join :: Monad m => m m a -> m a
- Monad: liftM :: Monad m => (a1 -> r) -> m a1 -> m r
- Monad: liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
- Monad: liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
- Monad: liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r
- Monad: liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
- Monad: mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c])
- Monad: mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
- Monad: mplus :: MonadPlus m => m a -> m a -> m a
- Monad: mzero :: MonadPlus m => m a
- Monad: orM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool
- Monad: replicateM :: Applicative m => Int -> m a -> m [a]
- Monad: replicateM_ :: Applicative m => Int -> m a -> m ()
- Monad: return :: Monad m => a -> m a
- Monad: zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c]
- Monad: zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m ()
- Monad.Either: fromLeft :: a -> Either a b -> a
- Monad.Either: fromRight :: b -> Either a b -> b
- Monad.Either: leftToMaybe :: Either l r -> Maybe l
- Monad.Either: maybeToLeft :: r -> Maybe l -> Either l r
- Monad.Either: maybeToRight :: l -> Maybe r -> Either l r
- Monad.Either: rightToMaybe :: Either l r -> Maybe r
- Monad.Either: whenLeft :: Applicative f => Either l r -> (l -> f ()) -> f ()
- Monad.Either: whenLeftM :: Monad m => m (Either l r) -> (l -> m ()) -> m ()
- Monad.Either: whenRight :: Applicative f => Either l r -> (r -> f ()) -> f ()
- Monad.Either: whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m ()
- Monad.Maybe: maybeToMonoid :: Monoid m => Maybe m -> m
- Monad.Maybe: whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()
- Monad.Maybe: whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()
- Monad.Maybe: whenNothing :: Applicative f => Maybe a -> f a -> f a
- Monad.Maybe: whenNothingM :: Monad m => m (Maybe a) -> m a -> m a
- Monad.Maybe: whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m ()
- Monad.Maybe: whenNothing_ :: Applicative f => Maybe a -> f () -> f ()
- Monad.Trans: evaluatingState :: s -> State s a -> a
- Monad.Trans: evaluatingStateT :: Functor f => s -> StateT s f a -> f a
- Monad.Trans: executingState :: s -> State s a -> s
- Monad.Trans: executingStateT :: Functor f => s -> StateT s f a -> f s
- Monad.Trans: usingReader :: r -> Reader r a -> a
- Monad.Trans: usingReaderT :: r -> ReaderT r m a -> m a
- Monad.Trans: usingState :: s -> State s a -> (a, s)
- Monad.Trans: usingStateT :: s -> StateT s m a -> m (a, s)
- Nub: hashNub :: (Eq a, Hashable a) => [a] -> [a]
- Nub: ordNub :: (Ord a) => [a] -> [a]
- Nub: sortNub :: (Ord a) => [a] -> [a]
- Nub: unstableNub :: (Eq a, Hashable a) => [a] -> [a]
- Print: class Print a
- Print: instance Print.Print Data.ByteString.Internal.ByteString
- Print: instance Print.Print Data.ByteString.Lazy.Internal.ByteString
- Print: instance Print.Print Data.Text.Internal.Lazy.Text
- Print: instance Print.Print Data.Text.Internal.Text
- Print: instance Print.Print [GHC.Types.Char]
- Print: print :: forall a m. (MonadIO m, Show a) => a -> m ()
- Print: putLText :: MonadIO m => Text -> m ()
- Print: putStr :: (Print a, MonadIO m) => a -> m ()
- Print: putStrLn :: (Print a, MonadIO m) => a -> m ()
- Print: putText :: MonadIO m => Text -> m ()
- String: class Buildable p
- String: class ConvertUtf8 a b
- String: class ToLText a
- String: class ToString a
- String: class ToText a
- String: decodeUtf8 :: ConvertUtf8 a b => b -> a
- String: decodeUtf8Strict :: ConvertUtf8 a b => b -> Either UnicodeException a
- String: encodeUtf8 :: ConvertUtf8 a b => a -> b
- String: instance String.ConvertUtf8 Data.Text.Internal.Lazy.Text Data.ByteString.Internal.ByteString
- String: instance String.ConvertUtf8 Data.Text.Internal.Lazy.Text Data.ByteString.Lazy.Internal.ByteString
- String: instance String.ConvertUtf8 Data.Text.Internal.Text Data.ByteString.Internal.ByteString
- String: instance String.ConvertUtf8 Data.Text.Internal.Text Data.ByteString.Lazy.Internal.ByteString
- String: instance String.ConvertUtf8 GHC.Base.String Data.ByteString.Internal.ByteString
- String: instance String.ConvertUtf8 GHC.Base.String Data.ByteString.Lazy.Internal.ByteString
- String: instance String.ToLText Data.Text.Internal.Lazy.Text
- String: instance String.ToLText Data.Text.Internal.Text
- String: instance String.ToLText GHC.Base.String
- String: instance String.ToString Data.Text.Internal.Lazy.Text
- String: instance String.ToString Data.Text.Internal.Text
- String: instance String.ToString GHC.Base.String
- String: instance String.ToText Data.Text.Internal.Lazy.Text
- String: instance String.ToText Data.Text.Internal.Text
- String: instance String.ToText GHC.Base.String
- String: pretty :: Buildable a => a -> Text
- String: prettyL :: Buildable a => a -> LText
- String: readEither :: (ToString a, Read b) => a -> Either Text b
- String: show :: forall b a. (Show a, IsString b) => a -> b
- String: toLText :: ToLText a => a -> Text
- String: toString :: ToString a => a -> String
- String: toText :: ToText a => a -> Text
- String: type LByteString = ByteString
- String: type LText = Text
- TypeOps: type ($) k k1 (f :: k -> k1) (a :: k) = f a
- TypeOps: type With a b = a <+> b
- Universum: evaluateNF :: (NFData a, MonadIO m) => a -> m a
- Universum: evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
- Universum: evaluateWHNF :: MonadIO m => a -> m a
- Universum: evaluateWHNF_ :: MonadIO m => a -> m ()
- Universum: identity :: a -> a
- Universum: map :: Functor f => (a -> b) -> f a -> f b
- Universum: uncons :: [a] -> Maybe (a, [a])
- Universum: unsnoc :: [x] -> Maybe ([x], x)
- Unsafe: unsafeFromJust :: Maybe a -> a
- Unsafe: unsafeHead :: [a] -> a
- Unsafe: unsafeIndex :: [a] -> Int -> a
- Unsafe: unsafeInit :: [a] -> [a]
- Unsafe: unsafeLast :: [a] -> a
- Unsafe: unsafeTail :: [a] -> [a]
- VarArg: (...) :: SuperComposition a b c => a -> b -> c
- VarArg: class SuperComposition a b c | a b -> c
- VarArg: instance (VarArg.SuperComposition (a -> b) d r1, r ~ (c -> r1)) => VarArg.SuperComposition (a -> b) (c -> d) r
- VarArg: instance (a ~ c, r ~ b) => VarArg.SuperComposition (a -> b) c r
+ Universum.Applicative: pass :: Applicative f => f ()
+ Universum.Base: ($!) :: (a -> b) -> a -> b
+ Universum.Base: infixr 0 $!
+ Universum.Bool.Guard: guardM :: MonadPlus m => m Bool -> m ()
+ Universum.Bool.Guard: ifM :: Monad m => m Bool -> m a -> m a -> m a
+ Universum.Bool.Guard: unlessM :: Monad m => m Bool -> m () -> m ()
+ Universum.Bool.Guard: whenM :: Monad m => m Bool -> m () -> m ()
+ Universum.Container.Class: all :: Container t => (Element t -> Bool) -> t -> Bool
+ Universum.Container.Class: and :: (Container t, Element t ~ Bool) => t -> Bool
+ Universum.Container.Class: any :: Container t => (Element t -> Bool) -> t -> Bool
+ Universum.Container.Class: asum :: (Container t, Alternative f, Element t ~ f a) => t -> f a
+ Universum.Container.Class: class ToList t => Container t where type ElementConstraint t :: * -> Constraint type ElementConstraint t = Eq foldr = foldr foldl = foldl foldl' = foldl' length = length elem = elem maximum = maximum minimum = minimum foldMap f = foldr (mappend . f) mempty fold = foldMap id foldr' f z0 xs = foldl f' id xs z0 where f' k x z = k $! f x z foldr1 f xs = fromMaybe (errorWithoutStackTrace "foldr1: empty structure") (foldr mf Nothing xs) where mf x m = Just (case m of { Nothing -> x Just y -> f x y }) foldl1 f xs = fromMaybe (errorWithoutStackTrace "foldl1: empty structure") (foldl mf Nothing xs) where mf m y = Just (case m of { Nothing -> y Just x -> f x y }) notElem x = not . elem x all p = getAll #. foldMap (All #. p) any p = getAny #. foldMap (Any #. p) and = getAll #. foldMap All or = getAny #. foldMap Any find p = getFirst . foldMap (\ x -> First (if p x then Just x else Nothing)) safeHead = foldr (\ x _ -> Just x) Nothing where {
+ Universum.Container.Class: class One x where type OneItem x where {
+ Universum.Container.Class: class ToList t where type Element t :: * type Element t = ElementDefault t toList = toList null = null . toList where {
+ Universum.Container.Class: elem :: (Container t, Foldable f, t ~ f a, Element t ~ a, ElementConstraint t ~ Eq, ElementConstraint t (Element t)) => Element t -> t -> Bool
+ Universum.Container.Class: find :: Container t => (Element t -> Bool) -> t -> Maybe (Element t)
+ Universum.Container.Class: fold :: (Container t, Monoid (Element t)) => t -> Element t
+ Universum.Container.Class: foldMap :: (Container t, Monoid m) => (Element t -> m) -> t -> m
+ Universum.Container.Class: foldl :: (Container t, Foldable f, t ~ f a, Element t ~ a) => (b -> Element t -> b) -> b -> t -> b
+ Universum.Container.Class: foldl' :: (Container t, Foldable f, t ~ f a, Element t ~ a) => (b -> Element t -> b) -> b -> t -> b
+ Universum.Container.Class: foldl1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t
+ Universum.Container.Class: foldr :: (Container t, Foldable f, t ~ f a, Element t ~ a) => (Element t -> b -> b) -> b -> t -> b
+ Universum.Container.Class: foldr' :: Container t => (Element t -> b -> b) -> b -> t -> b
+ Universum.Container.Class: foldr1 :: Container t => (Element t -> Element t -> Element t) -> t -> Element t
+ Universum.Container.Class: forM_ :: (Container t, Monad m) => t -> (Element t -> m b) -> m ()
+ Universum.Container.Class: for_ :: (Container t, Applicative f) => t -> (Element t -> f b) -> f ()
+ Universum.Container.Class: instance (GHC.Classes.Eq a, Data.Hashable.Class.Hashable a) => Universum.Container.Class.CanHash a
+ Universum.Container.Class: instance (TypeError ...) => Universum.Container.Class.Container (Data.Either.Either a b)
+ Universum.Container.Class: instance (TypeError ...) => Universum.Container.Class.Container (Data.Functor.Identity.Identity a)
+ Universum.Container.Class: instance (TypeError ...) => Universum.Container.Class.Container (GHC.Base.Maybe a)
+ Universum.Container.Class: instance (TypeError ...) => Universum.Container.Class.Container (a, b)
+ Universum.Container.Class: instance (TypeError ...) => Universum.Container.Class.ToList (a, b)
+ Universum.Container.Class: instance Data.Hashable.Class.Hashable k => Universum.Container.Class.One (Data.HashMap.Base.HashMap k v)
+ Universum.Container.Class: instance Data.Hashable.Class.Hashable v => Universum.Container.Class.One (Data.HashSet.HashSet v)
+ Universum.Container.Class: instance Data.Primitive.Types.Prim a => Universum.Container.Class.One (Data.Vector.Primitive.Vector a)
+ Universum.Container.Class: instance Data.Vector.Unboxed.Base.Unbox a => Universum.Container.Class.One (Data.Vector.Unboxed.Base.Vector a)
+ Universum.Container.Class: instance Foreign.Storable.Storable a => Universum.Container.Class.One (Data.Vector.Storable.Vector a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Control.Applicative.ZipList a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Functor.Const.Const a b)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.HashMap.Base.HashMap k v)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.HashSet.HashSet v)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.IntMap.Base.IntMap v)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.List.NonEmpty.NonEmpty a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Map.Base.Map k v)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Monoid.Dual a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Monoid.First a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Monoid.Last a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Monoid.Product a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Monoid.Sum a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Sequence.Seq a)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Set.Base.Set v)
+ Universum.Container.Class: instance Universum.Container.Class.Container (Data.Vector.Vector a)
+ Universum.Container.Class: instance Universum.Container.Class.Container Data.ByteString.Internal.ByteString
+ Universum.Container.Class: instance Universum.Container.Class.Container Data.ByteString.Lazy.Internal.ByteString
+ Universum.Container.Class: instance Universum.Container.Class.Container Data.IntSet.Base.IntSet
+ Universum.Container.Class: instance Universum.Container.Class.Container Data.Text.Internal.Lazy.Text
+ Universum.Container.Class: instance Universum.Container.Class.Container Data.Text.Internal.Text
+ Universum.Container.Class: instance Universum.Container.Class.Container [a]
+ Universum.Container.Class: instance Universum.Container.Class.One (Data.IntMap.Base.IntMap v)
+ Universum.Container.Class: instance Universum.Container.Class.One (Data.List.NonEmpty.NonEmpty a)
+ Universum.Container.Class: instance Universum.Container.Class.One (Data.Map.Base.Map k v)
+ Universum.Container.Class: instance Universum.Container.Class.One (Data.Sequence.Seq a)
+ Universum.Container.Class: instance Universum.Container.Class.One (Data.Set.Base.Set v)
+ Universum.Container.Class: instance Universum.Container.Class.One (Data.Vector.Vector a)
+ Universum.Container.Class: instance Universum.Container.Class.One Data.ByteString.Internal.ByteString
+ Universum.Container.Class: instance Universum.Container.Class.One Data.ByteString.Lazy.Internal.ByteString
+ Universum.Container.Class: instance Universum.Container.Class.One Data.IntSet.Base.IntSet
+ Universum.Container.Class: instance Universum.Container.Class.One Data.Text.Internal.Lazy.Text
+ Universum.Container.Class: instance Universum.Container.Class.One Data.Text.Internal.Text
+ Universum.Container.Class: instance Universum.Container.Class.One [a]
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Control.Applicative.ZipList a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Either.Either a b)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Functor.Const.Const a b)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Functor.Identity.Identity a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.HashMap.Base.HashMap k v)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.HashSet.HashSet v)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.IntMap.Base.IntMap v)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.List.NonEmpty.NonEmpty a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Map.Base.Map k v)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Monoid.Dual a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Monoid.First a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Monoid.Last a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Monoid.Product a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Monoid.Sum a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Sequence.Seq a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Set.Base.Set v)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (Data.Vector.Vector a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList (GHC.Base.Maybe a)
+ Universum.Container.Class: instance Universum.Container.Class.ToList Data.ByteString.Internal.ByteString
+ Universum.Container.Class: instance Universum.Container.Class.ToList Data.ByteString.Lazy.Internal.ByteString
+ Universum.Container.Class: instance Universum.Container.Class.ToList Data.IntSet.Base.IntSet
+ Universum.Container.Class: instance Universum.Container.Class.ToList Data.Text.Internal.Lazy.Text
+ Universum.Container.Class: instance Universum.Container.Class.ToList Data.Text.Internal.Text
+ Universum.Container.Class: instance Universum.Container.Class.ToList [a]
+ Universum.Container.Class: length :: (Container t, Foldable f, t ~ f a, Element t ~ a) => t -> Int
+ Universum.Container.Class: mapM_ :: (Container t, Monad m) => (Element t -> m b) -> t -> m ()
+ Universum.Container.Class: maximum :: (Container t, Foldable f, t ~ f a, Element t ~ a, Ord (Element t)) => t -> Element t
+ Universum.Container.Class: minimum :: (Container t, Foldable f, t ~ f a, Element t ~ a, Ord (Element t)) => t -> Element t
+ Universum.Container.Class: notElem :: (Container t, ElementConstraint t (Element t)) => Element t -> t -> Bool
+ Universum.Container.Class: null :: ToList t => t -> Bool
+ Universum.Container.Class: one :: One x => OneItem x -> x
+ Universum.Container.Class: or :: (Container t, Element t ~ Bool) => t -> Bool
+ Universum.Container.Class: product :: (Container t, Num (Element t)) => t -> Element t
+ Universum.Container.Class: safeHead :: Container t => t -> Maybe (Element t)
+ Universum.Container.Class: sequenceA_ :: (Container t, Applicative f, Element t ~ f a) => t -> f ()
+ Universum.Container.Class: sequence_ :: (Container t, Monad m, Element t ~ m a) => t -> m ()
+ Universum.Container.Class: sum :: (Container t, Num (Element t)) => t -> Element t
+ Universum.Container.Class: toList :: (ToList t, Foldable f, t ~ f a, Element t ~ a) => t -> [Element t]
+ Universum.Container.Class: traverse_ :: (Container t, Applicative f) => (Element t -> f b) -> t -> f ()
+ Universum.Container.Class: type Element t = ElementDefault t;
+ Universum.Container.Class: type ElementConstraint t = Eq;
+ Universum.Container.Class: type family OneItem x;
+ Universum.Container.Class: }
+ Universum.Debug: Undefined :: Undefined
+ Universum.Debug: data Undefined
+ Universum.Debug: error :: forall (r :: RuntimeRep). forall (a :: TYPE r). HasCallStack => Text -> a
+ Universum.Debug: instance Data.Data.Data Universum.Debug.Undefined
+ Universum.Debug: instance GHC.Classes.Eq Universum.Debug.Undefined
+ Universum.Debug: instance GHC.Classes.Ord Universum.Debug.Undefined
+ Universum.Debug: instance GHC.Enum.Bounded Universum.Debug.Undefined
+ Universum.Debug: instance GHC.Enum.Enum Universum.Debug.Undefined
+ Universum.Debug: instance GHC.Generics.Generic Universum.Debug.Undefined
+ Universum.Debug: instance GHC.Read.Read Universum.Debug.Undefined
+ Universum.Debug: instance GHC.Show.Show Universum.Debug.Undefined
+ Universum.Debug: trace :: Print b => b -> a -> a
+ Universum.Debug: traceId :: Text -> Text
+ Universum.Debug: traceM :: (Monad m) => Text -> m ()
+ Universum.Debug: traceShow :: Show a => a -> b -> b
+ Universum.Debug: traceShowId :: Show a => a -> a
+ Universum.Debug: traceShowM :: (Show a, Monad m) => a -> m ()
+ Universum.Debug: undefined :: forall (r :: RuntimeRep). forall (a :: TYPE r). HasCallStack => a
+ Universum.DeepSeq: evaluateNF :: (NFData a, MonadIO m) => a -> m a
+ Universum.DeepSeq: evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
+ Universum.DeepSeq: evaluateWHNF :: MonadIO m => a -> m a
+ Universum.DeepSeq: evaluateWHNF_ :: MonadIO m => a -> m ()
+ Universum.Exception: note :: (MonadError e m) => e -> Maybe a -> m a
+ Universum.Function: identity :: a -> a
+ Universum.Functor.Fmap: (<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
+ Universum.Functor.Fmap: infixl 4 <<$>>
+ Universum.Functor.Fmap: map :: Functor f => (a -> b) -> f a -> f b
+ Universum.Lifted.Concurrent: atomically :: MonadIO m => STM a -> m a
+ Universum.Lifted.Concurrent: data MVar a :: * -> *
+ Universum.Lifted.Concurrent: data STM a :: * -> *
+ Universum.Lifted.Concurrent: data TVar a :: * -> *
+ Universum.Lifted.Concurrent: modifyTVar' :: TVar a -> (a -> a) -> STM ()
+ Universum.Lifted.Concurrent: newEmptyMVar :: MonadIO m => m (MVar a)
+ Universum.Lifted.Concurrent: newMVar :: MonadIO m => a -> m (MVar a)
+ Universum.Lifted.Concurrent: newTVar :: a -> STM (TVar a)
+ Universum.Lifted.Concurrent: newTVarIO :: MonadIO m => a -> m (TVar a)
+ Universum.Lifted.Concurrent: putMVar :: MonadIO m => MVar a -> a -> m ()
+ Universum.Lifted.Concurrent: readMVar :: MonadIO m => MVar a -> m a
+ Universum.Lifted.Concurrent: readTVar :: TVar a -> STM a
+ Universum.Lifted.Concurrent: readTVarIO :: MonadIO m => TVar a -> m a
+ Universum.Lifted.Concurrent: swapMVar :: MonadIO m => MVar a -> a -> m a
+ Universum.Lifted.Concurrent: takeMVar :: MonadIO m => MVar a -> m a
+ Universum.Lifted.Concurrent: tryPutMVar :: MonadIO m => MVar a -> a -> m Bool
+ Universum.Lifted.Concurrent: tryReadMVar :: MonadIO m => MVar a -> m (Maybe a)
+ Universum.Lifted.Concurrent: tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a)
+ Universum.Lifted.Concurrent: writeTVar :: TVar a -> a -> STM ()
+ Universum.Lifted.Env: die :: MonadIO m => String -> m ()
+ Universum.Lifted.Env: exitFailure :: MonadIO m => m a
+ Universum.Lifted.Env: exitSuccess :: MonadIO m => m a
+ Universum.Lifted.Env: exitWith :: MonadIO m => ExitCode -> m a
+ Universum.Lifted.Env: getArgs :: MonadIO m => m [String]
+ Universum.Lifted.File: appendFile :: MonadIO m => FilePath -> Text -> m ()
+ Universum.Lifted.File: getContents :: MonadIO m => m Text
+ Universum.Lifted.File: getLine :: MonadIO m => m Text
+ Universum.Lifted.File: interact :: MonadIO m => (Text -> Text) -> m ()
+ Universum.Lifted.File: openFile :: MonadIO m => FilePath -> IOMode -> m Handle
+ Universum.Lifted.File: readFile :: MonadIO m => FilePath -> m Text
+ Universum.Lifted.File: writeFile :: MonadIO m => FilePath -> Text -> m ()
+ Universum.Lifted.IORef: atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
+ Universum.Lifted.IORef: atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
+ Universum.Lifted.IORef: atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()
+ Universum.Lifted.IORef: data IORef a :: * -> *
+ Universum.Lifted.IORef: modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Universum.Lifted.IORef: modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Universum.Lifted.IORef: newIORef :: MonadIO m => a -> m (IORef a)
+ Universum.Lifted.IORef: readIORef :: MonadIO m => IORef a -> m a
+ Universum.Lifted.IORef: writeIORef :: MonadIO m => IORef a -> a -> m ()
+ Universum.Lifted.ST: stToIO :: MonadIO m => ST RealWorld a -> m a
+ Universum.List.Safe: list :: [b] -> (a -> b) -> [a] -> [b]
+ Universum.List.Safe: uncons :: [a] -> Maybe (a, [a])
+ Universum.List.Safe: whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()
+ Universum.List.Safe: whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m ()
+ Universum.Monad.Container: allM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool
+ Universum.Monad.Container: andM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool
+ Universum.Monad.Container: anyM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool
+ Universum.Monad.Container: concatForM :: (Applicative f, Monoid m, Container (l m), Element (l m) ~ m, Traversable l) => l a -> (a -> f m) -> f m
+ Universum.Monad.Container: concatMapM :: (Applicative f, Monoid m, Container (l m), Element (l m) ~ m, Traversable l) => (a -> f m) -> l a -> f m
+ Universum.Monad.Container: orM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool
+ Universum.Monad.Either: fromLeft :: a -> Either a b -> a
+ Universum.Monad.Either: fromRight :: b -> Either a b -> b
+ Universum.Monad.Either: leftToMaybe :: Either l r -> Maybe l
+ Universum.Monad.Either: maybeToLeft :: r -> Maybe l -> Either l r
+ Universum.Monad.Either: maybeToRight :: l -> Maybe r -> Either l r
+ Universum.Monad.Either: rightToMaybe :: Either l r -> Maybe r
+ Universum.Monad.Either: whenLeft :: Applicative f => Either l r -> (l -> f ()) -> f ()
+ Universum.Monad.Either: whenLeftM :: Monad m => m (Either l r) -> (l -> m ()) -> m ()
+ Universum.Monad.Either: whenRight :: Applicative f => Either l r -> (r -> f ()) -> f ()
+ Universum.Monad.Either: whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m ()
+ Universum.Monad.Maybe: whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()
+ Universum.Monad.Maybe: whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()
+ Universum.Monad.Maybe: whenNothing :: Applicative f => Maybe a -> f a -> f a
+ Universum.Monad.Maybe: whenNothingM :: Monad m => m (Maybe a) -> m a -> m a
+ Universum.Monad.Maybe: whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m ()
+ Universum.Monad.Maybe: whenNothing_ :: Applicative f => Maybe a -> f () -> f ()
+ Universum.Monad.Reexport: (<$!>) :: Monad m => (a -> b) -> m a -> m b
+ Universum.Monad.Reexport: (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
+ Universum.Monad.Reexport: (=<<) :: Monad m => (a -> m b) -> m a -> m b
+ Universum.Monad.Reexport: (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
+ Universum.Monad.Reexport: (>>) :: Monad m => m a -> m b -> m b
+ Universum.Monad.Reexport: (>>=) :: Monad m => m a -> (a -> m b) -> m b
+ Universum.Monad.Reexport: ap :: Monad m => m (a -> b) -> m a -> m b
+ Universum.Monad.Reexport: class Applicative m => Monad (m :: * -> *)
+ Universum.Monad.Reexport: class Monad m => MonadFail (m :: * -> *)
+ Universum.Monad.Reexport: class (Alternative m, Monad m) => MonadPlus (m :: * -> *)
+ Universum.Monad.Reexport: fail :: MonadFail m => String -> m a
+ Universum.Monad.Reexport: filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]
+ Universum.Monad.Reexport: foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
+ Universum.Monad.Reexport: foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m ()
+ Universum.Monad.Reexport: forever :: Applicative f => f a -> f b
+ Universum.Monad.Reexport: infixl 4 <$!>
+ Universum.Monad.Reexport: infixr 1 <=<
+ Universum.Monad.Reexport: join :: Monad m => m (m a) -> m a
+ Universum.Monad.Reexport: liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
+ Universum.Monad.Reexport: liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
+ Universum.Monad.Reexport: liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r
+ Universum.Monad.Reexport: liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
+ Universum.Monad.Reexport: mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c])
+ Universum.Monad.Reexport: mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
+ Universum.Monad.Reexport: mplus :: MonadPlus m => m a -> m a -> m a
+ Universum.Monad.Reexport: mzero :: MonadPlus m => m a
+ Universum.Monad.Reexport: replicateM :: Applicative m => Int -> m a -> m [a]
+ Universum.Monad.Reexport: replicateM_ :: Applicative m => Int -> m a -> m ()
+ Universum.Monad.Reexport: return :: Monad m => a -> m a
+ Universum.Monad.Reexport: zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c]
+ Universum.Monad.Reexport: zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m ()
+ Universum.Monad.Trans: evaluatingState :: s -> State s a -> a
+ Universum.Monad.Trans: evaluatingStateT :: Functor f => s -> StateT s f a -> f a
+ Universum.Monad.Trans: executingState :: s -> State s a -> s
+ Universum.Monad.Trans: executingStateT :: Functor f => s -> StateT s f a -> f s
+ Universum.Monad.Trans: usingReader :: r -> Reader r a -> a
+ Universum.Monad.Trans: usingReaderT :: r -> ReaderT r m a -> m a
+ Universum.Monad.Trans: usingState :: s -> State s a -> (a, s)
+ Universum.Monad.Trans: usingStateT :: s -> StateT s m a -> m (a, s)
+ Universum.Monoid: maybeToMonoid :: Monoid m => Maybe m -> m
+ Universum.Nub: hashNub :: (Eq a, Hashable a) => [a] -> [a]
+ Universum.Nub: ordNub :: (Ord a) => [a] -> [a]
+ Universum.Nub: sortNub :: (Ord a) => [a] -> [a]
+ Universum.Nub: unstableNub :: (Eq a, Hashable a) => [a] -> [a]
+ Universum.Print: class Print a
+ Universum.Print: instance Universum.Print.Print Data.ByteString.Internal.ByteString
+ Universum.Print: instance Universum.Print.Print Data.ByteString.Lazy.Internal.ByteString
+ Universum.Print: instance Universum.Print.Print Data.Text.Internal.Lazy.Text
+ Universum.Print: instance Universum.Print.Print Data.Text.Internal.Text
+ Universum.Print: instance Universum.Print.Print [GHC.Types.Char]
+ Universum.Print: print :: forall a m. (MonadIO m, Show a) => a -> m ()
+ Universum.Print: putLText :: MonadIO m => Text -> m ()
+ Universum.Print: putLTextLn :: MonadIO m => Text -> m ()
+ Universum.Print: putStr :: (Print a, MonadIO m) => a -> m ()
+ Universum.Print: putStrLn :: (Print a, MonadIO m) => a -> m ()
+ Universum.Print: putText :: MonadIO m => Text -> m ()
+ Universum.Print: putTextLn :: MonadIO m => Text -> m ()
+ Universum.String.Conversion: class ConvertUtf8 a b
+ Universum.String.Conversion: class ToLText a
+ Universum.String.Conversion: class ToString a
+ Universum.String.Conversion: class ToText a
+ Universum.String.Conversion: decodeUtf8 :: ConvertUtf8 a b => b -> a
+ Universum.String.Conversion: decodeUtf8Strict :: ConvertUtf8 a b => b -> Either UnicodeException a
+ Universum.String.Conversion: encodeUtf8 :: ConvertUtf8 a b => a -> b
+ Universum.String.Conversion: instance Universum.String.Conversion.ConvertUtf8 Data.Text.Internal.Lazy.Text Data.ByteString.Internal.ByteString
+ Universum.String.Conversion: instance Universum.String.Conversion.ConvertUtf8 Data.Text.Internal.Lazy.Text Data.ByteString.Lazy.Internal.ByteString
+ Universum.String.Conversion: instance Universum.String.Conversion.ConvertUtf8 Data.Text.Internal.Text Data.ByteString.Internal.ByteString
+ Universum.String.Conversion: instance Universum.String.Conversion.ConvertUtf8 Data.Text.Internal.Text Data.ByteString.Lazy.Internal.ByteString
+ Universum.String.Conversion: instance Universum.String.Conversion.ConvertUtf8 GHC.Base.String Data.ByteString.Internal.ByteString
+ Universum.String.Conversion: instance Universum.String.Conversion.ConvertUtf8 GHC.Base.String Data.ByteString.Lazy.Internal.ByteString
+ Universum.String.Conversion: instance Universum.String.Conversion.ToLText Data.Text.Internal.Lazy.Text
+ Universum.String.Conversion: instance Universum.String.Conversion.ToLText Data.Text.Internal.Text
+ Universum.String.Conversion: instance Universum.String.Conversion.ToLText GHC.Base.String
+ Universum.String.Conversion: instance Universum.String.Conversion.ToString Data.Text.Internal.Lazy.Text
+ Universum.String.Conversion: instance Universum.String.Conversion.ToString Data.Text.Internal.Text
+ Universum.String.Conversion: instance Universum.String.Conversion.ToString GHC.Base.String
+ Universum.String.Conversion: instance Universum.String.Conversion.ToText Data.Text.Internal.Lazy.Text
+ Universum.String.Conversion: instance Universum.String.Conversion.ToText Data.Text.Internal.Text
+ Universum.String.Conversion: instance Universum.String.Conversion.ToText GHC.Base.String
+ Universum.String.Conversion: pretty :: Buildable a => a -> Text
+ Universum.String.Conversion: prettyL :: Buildable a => a -> LText
+ Universum.String.Conversion: readEither :: (ToString a, Read b) => a -> Either Text b
+ Universum.String.Conversion: show :: forall b a. (Show a, IsString b) => a -> b
+ Universum.String.Conversion: toLText :: ToLText a => a -> Text
+ Universum.String.Conversion: toString :: ToString a => a -> String
+ Universum.String.Conversion: toText :: ToText a => a -> Text
+ Universum.String.Conversion: type LByteString = ByteString
+ Universum.String.Conversion: type LText = Text
+ Universum.TypeOps: type ($) k k1 (f :: k1 -> k) (a :: k1) = f a
+ Universum.TypeOps: type With a b = a <+> b
+ Universum.VarArg: (...) :: SuperComposition a b c => a -> b -> c
+ Universum.VarArg: class SuperComposition a b c | a b -> c
+ Universum.VarArg: instance (Universum.VarArg.SuperComposition (a -> b) d r1, r ~ (c -> r1)) => Universum.VarArg.SuperComposition (a -> b) (c -> d) r
+ Universum.VarArg: instance (a ~ c, r ~ b) => Universum.VarArg.SuperComposition (a -> b) c r
Files
- CHANGES.md +23/−5
- benchmark/Main.hs +32/−11
- src/Applicative.hs +0/−39
- src/Base.hs +0/−89
- src/Bool.hs +0/−75
- src/Container.hs +0/−9
- src/Container/Class.hs +0/−743
- src/Container/Reexport.hs +0/−23
- src/Debug.hs +0/−78
- src/Exceptions.hs +0/−60
- src/Functor.hs +0/−23
- src/Lifted.hs +0/−25
- src/Lifted/Concurrent.hs +0/−112
- src/Lifted/Env.hs +0/−47
- src/Lifted/File.hs +0/−65
- src/Lifted/IORef.hs +0/−63
- src/List.hs +0/−60
- src/Monad.hs +0/−227
- src/Monad/Either.hs +0/−105
- src/Monad/Maybe.hs +0/−79
- src/Monad/Trans.hs +0/−84
- src/Nub.hs +0/−76
- src/Print.hs +0/−68
- src/String.hs +0/−196
- src/TypeOps.hs +0/−59
- src/Universum.hs +44/−151
- src/Universum/Applicative.hs +40/−0
- src/Universum/Base.hs +127/−0
- src/Universum/Bool.hs +12/−0
- src/Universum/Bool/Guard.hs +57/−0
- src/Universum/Bool/Reexport.hs +7/−0
- src/Universum/Container.hs +9/−0
- src/Universum/Container/Class.hs +775/−0
- src/Universum/Container/Reexport.hs +25/−0
- src/Universum/Debug.hs +96/−0
- src/Universum/DeepSeq.hs +32/−0
- src/Universum/Exception.hs +31/−0
- src/Universum/Function.hs +10/−0
- src/Universum/Functor.hs +11/−0
- src/Universum/Functor/Fmap.hs +21/−0
- src/Universum/Functor/Reexport.hs +13/−0
- src/Universum/Lifted.hs +17/−0
- src/Universum/Lifted/Concurrent.hs +110/−0
- src/Universum/Lifted/Env.hs +48/−0
- src/Universum/Lifted/File.hs +66/−0
- src/Universum/Lifted/IORef.hs +62/−0
- src/Universum/Lifted/ST.hs +12/−0
- src/Universum/List.hs +11/−0
- src/Universum/List/Reexport.hs +24/−0
- src/Universum/List/Safe.hs +57/−0
- src/Universum/Monad.hs +17/−0
- src/Universum/Monad/Container.hs +142/−0
- src/Universum/Monad/Either.hs +103/−0
- src/Universum/Monad/Maybe.hs +61/−0
- src/Universum/Monad/Reexport.hs +97/−0
- src/Universum/Monad/Trans.hs +67/−0
- src/Universum/Monoid.hs +33/−0
- src/Universum/Nub.hs +77/−0
- src/Universum/Print.hs +81/−0
- src/Universum/String.hs +9/−0
- src/Universum/String/Conversion.hs +171/−0
- src/Universum/String/Reexport.hs +27/−0
- src/Universum/TypeOps.hs +59/−0
- src/Universum/VarArg.hs +52/−0
- src/Unsafe.hs +0/−42
- src/VarArg.hs +0/−52
- universum.cabal +42/−31
CHANGES.md view
@@ -1,10 +1,28 @@-0.9.2+1.0.0 ===== -* [#114](https://github.com/serokell/universum/issues/114):- Reexport more functions from `safe-exceptions`.-* [#100](https://github.com/serokell/universum/issues/100):- Add `bug` function = `impureThrow`.+* [#90](https://github.com/serokell/universum/issues/90):+ Improve project structure.+* [#89](https://github.com/serokell/universum/issues/89):+ Add export of `Universum.Nub` module to `Universum`.+* Add `listToMaybe` to `Universum.Monad.Reexport`.+* [#81](https://github.com/serokell/universum/issues/81):+ Make `putText` and `putLText` to be versions of `putStr`.+ Add `putTextLn` and `putLTextLn` -- versions of `putStrLn`.+* [#5](https://github.com/serokell/universum/issues/5):+ Add safe versions of `head`, `tail`, `init`, `last` functions for `NonEmpty` list.+ Old `head` (which returns `Maybe`) is renamed to `safeHead`.+ Reexports from `safe` are removed.+* Remove `unsnoc` (this function is very slow and shouldn't be used).+* [#88](https://github.com/serokell/universum/issues/88):+ Add `HasCallStack =>` to `error` and `undefined` functions.+* [#58](https://github.com/serokell/universum/issues/58):+ Make `Element` type family be associated type family.+ Remove `{-# OVERLAPPABLE #-}` instance for `ToList` and `Container`. Add default instances for basic types.+ Remove `WrappedList` `newtype` because it's not needed anymore.+ Remove `NontrivialContainer` constraint alias.+* [#56](https://github.com/serokell/universum/issues/56):+ Make `elem` and `notElem` faster for `Set` and `HashSet` by introducing `ElementConstraint` associated type family. 0.9.1 =====
benchmark/Main.hs view
@@ -1,19 +1,26 @@ {-# LANGUAGE ExplicitForAll #-} {-# LANGUAGE ScopedTypeVariables #-} -import Control.DeepSeq (NFData)-import Control.Monad.Identity (Identity (..))-import Criterion.Main (Benchmark, bench, bgroup, defaultMain, nf)-import Data.Hashable (Hashable)-import Data.List (group, head, nub, sort, zip5)-import qualified Data.List.NonEmpty as NonEmpty-import Data.Text (Text)-import qualified Data.Text as T+module Main where -import Monad (concatMapM)-import Nub (hashNub, ordNub, sortNub, unstableNub)-import VarArg ((...))+import Control.DeepSeq (NFData)+import Control.Monad.Identity (Identity (..))+import Criterion.Main (Benchmark, bench, bgroup, defaultMain, nf, whnf)+import Data.Hashable (Hashable)+import Data.List (group, head, nub, sort, zip5)+import Data.Text (Text) +import Universum.Monad (concatMapM)+import Universum.Nub (hashNub, ordNub, sortNub, unstableNub)+import Universum.VarArg ((...))++import qualified Data.Foldable as Foldable (elem)+import qualified Data.HashSet as HashSet (fromList)+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Set as Set (fromList)+import qualified Data.Text as T+import qualified Universum.Container as Container (elem)+ main :: IO () main = defaultMain [ bgroupList listOfSmall "small"@@ -22,6 +29,7 @@ , bgroupList (nStrings 'c') "big str" , bgroupSuperComposition , bgroupConcatMap+ , bgroupMember ] bgroupList :: forall a .@@ -146,3 +154,16 @@ concatIdentity :: Int -> Identity [()] concatIdentity n = concatMapM (Identity . pure) $ replicate n ()++-- | Checks that 'member' is implemented efficiently for 'Set' and 'HashSet'.+bgroupMember :: Benchmark+bgroupMember = do+ let testList = [1..100000] :: [Int]+ let sample = 50000+ let listSet = Set.fromList testList+ let listHashSet = HashSet.fromList testList+ bgroup "member" [ bench "Set/foldable" $ whnf (Foldable.elem sample) listSet+ , bench "Set/elem" $ whnf (Container.elem sample) listSet+ , bench "HashSet/Foldable" $ whnf (Foldable.elem sample) listHashSet+ , bench "HashSet/elem" $ whnf (Container.elem sample) listHashSet+ ]
− src/Applicative.hs
@@ -1,39 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE Safe #-}---- | Convenient utils to work with 'Applicative'. There were more functions in this module--- (see <https://www.stackage.org/haddock/lts-8.9/protolude-0.1.10/Applicative.html protolude version>)--- but only convenient ans most used are left.--module Applicative- ( pass- ) where--import Control.Applicative (Applicative (pure))---- | Shorter alias for @pure ()@.------ >>> pass :: Maybe ()--- Just ()-pass :: Applicative f => f ()-pass = pure ()--{--orAlt :: (Alternative f, Monoid a) => f a -> f a-orAlt f = f <|> pure mempty--orEmpty :: Alternative f => Bool -> a -> f a-orEmpty b a = if b then pure a else empty--eitherA :: Alternative f => f a -> f b -> f (Either a b)-eitherA a b = (Left <$> a) <|> (Right <$> b)--purer :: (Applicative f, Applicative g) => a -> f (g a)-purer = pure . pure--liftAA2 :: (Applicative f, Applicative g) => (a -> b -> c) -> f (g a) -> f (g b) -> f (g c)-liftAA2 = liftA2 . liftA2--(<<*>>) :: (Applicative f, Applicative g) => f (g (a -> b)) -> f (g a) -> f (g b)-(<<*>>) = liftA2 (<*>)--}
− src/Base.hs
@@ -1,89 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE Unsafe #-}---- | Reexports from @GHC.*@ modules of <https://www.stackage.org/lts-8.9/package/base-4.9.1.0 base>--- package.--module Base- ( module GHC.Base- , module GHC.Enum- , module GHC.Err- , module GHC.Exts- , module GHC.Float- , module GHC.Num- , module GHC.Real- , module GHC.Show-#if MIN_VERSION_base(4,10,0)- , module GHC.TypeNats-#else- , module GHC.TypeLits-#endif- , module GHC.Types--#if ( __GLASGOW_HASKELL__ >= 800 )- , module GHC.OverloadedLabels- , module GHC.ExecutionStack- , module GHC.Stack-#endif-- , ($!)- ) where---- Base GHC types-import GHC.Base (String, asTypeOf, maxInt, minInt, ord, seq, (++))-import GHC.Enum (Bounded (..), Enum (..), boundedEnumFrom,- boundedEnumFromThen)-import GHC.Err (error, undefined)-import GHC.Exts (Constraint, FunPtr, Ptr)-import GHC.Float (Double (..), Float (..), Floating (..), showFloat,- showSignedFloat)-import GHC.Num (Integer, Num (..), subtract)-import GHC.Real hiding ((%))-import GHC.Show (Show (..))-#if MIN_VERSION_base(4,10,0)-import GHC.TypeNats (CmpNat, KnownNat, Nat, SomeNat (..), natVal,- someNatVal)-#else-import GHC.TypeLits (CmpNat, KnownNat, Nat, SomeNat (..), natVal,- someNatVal)-#endif--import GHC.Types (Bool, Char, Coercible, IO, Int, Ordering, Word)---#if ( __GLASGOW_HASKELL__ >= 800 )-import GHC.ExecutionStack (getStackTrace, showStackTrace)-import GHC.OverloadedLabels (IsLabel (..))-import GHC.Stack (CallStack, HasCallStack, callStack,- currentCallStack, getCallStack, prettyCallStack,- prettySrcLoc, withFrozenCallStack)-#endif---- Pending GHC 8.2 we'll expose these.--{--import GHC.Records as X (- HasField(..)- )--<<<<<<< HEAD-=======-import Data.Kind as X (- type (*)- , type Type- )--}----- | Stricter version of 'Data.Function.$' operator.--- Default Prelude defines this at the toplevel module, so we do as well.------ >>> const 3 $ undefined--- 3--- >>> const 3 $! undefined--- CallStack (from HasCallStack):--- error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err-($!) :: (a -> b) -> a -> b-f $! x = let !vx = x in f vx-infixr 0 $!
− src/Bool.hs
@@ -1,75 +0,0 @@-{-# LANGUAGE Safe #-}---- | Convenient commonly used and very helpful functions to work with--- 'Bool' and also with monads.--module Bool- ( bool- , guard- , guardM- , ifM- , unless- , unlessM- , when- , whenM- ) where--import Control.Monad (Monad, MonadPlus, guard, unless, when, (>>=))-import Data.Bool (Bool)-import Data.Function (flip)---- | Reversed version of @if-then-else@.------ >>> bool 5 10 True--- 10--- >>> bool 5 10 False--- 5-bool :: a -> a -> Bool -> a-bool f t p = if p then t else f---- | Monadic version of 'when'.------ >>> whenM (pure False) $ putText "No text :("--- >>> whenM (pure True) $ putText "Yes text :)"--- Yes text :)--- >>> whenM (Just True) (pure ())--- Just ()--- >>> whenM (Just False) (pure ())--- Just ()--- >>> whenM Nothing (pure ())--- Nothing-whenM :: Monad m => m Bool -> m () -> m ()-whenM p m = p >>= flip when m-{-# INLINE whenM #-}---- | Monadic version of 'unless'.------ >>> unlessM (pure False) $ putText "No text :("--- No text :(--- >>> unlessM (pure True) $ putText "Yes text :)"-unlessM :: Monad m => m Bool -> m () -> m ()-unlessM p m = p >>= flip unless m-{-# INLINE unlessM #-}---- | Monadic version of @if-then-else@.------ >>> ifM (pure True) (putText "True text") (putText "False text")--- 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 = f >>= guard-{-# INLINE guardM #-}
− src/Container.hs
@@ -1,9 +0,0 @@--- | This module exports all container-related stuff.--module Container- ( module Container.Class- , module Container.Reexport- ) where--import Container.Class-import Container.Reexport
− src/Container/Class.hs
@@ -1,743 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE ConstrainedClassMethods #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}--{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}---- | Reimagined approach for 'Foldable' type hierarchy. Forbids usages--- of 'length' function and similar over 'Maybe' and other potentially unsafe--- data types. It was proposed to use @-XTypeApplication@ for such cases.--- But this approach is not robust enough because programmers are human and can--- easily forget to do this. For discussion see this topic:--- <https://www.reddit.com/r/haskell/comments/60r9hu/proposal_suggest_explicit_type_application_for/ Suggest explicit type application for Foldable length and friends>--module Container.Class- (- -- * Foldable-like classes and methods- Element- , ToList(..)- , Container(..)- , NontrivialContainer-- , WrappedList (..)-- , sum- , product-- , mapM_- , forM_- , traverse_- , for_- , sequenceA_- , sequence_- , asum-- -- * Others- , One(..)- ) where--import Control.Applicative (Alternative (..))-import Control.Monad.Identity (Identity)-import Data.Coerce (Coercible, coerce)-import Data.Foldable (Foldable)-import Data.Hashable (Hashable)-import Data.Maybe (fromMaybe)-import Data.Monoid (All (..), Any (..), First (..))-import Data.Word (Word8)-import Prelude hiding (Foldable (..), all, and, any, head, mapM_, notElem, or, sequence_)--#if __GLASGOW_HASKELL__ >= 800-import GHC.Err (errorWithoutStackTrace)-import GHC.TypeLits (ErrorMessage (..), Symbol, TypeError)-#endif--#if ( __GLASGOW_HASKELL__ >= 800 )-import qualified Data.List.NonEmpty as NE-#endif--import qualified Data.Foldable as F--import qualified Data.List as List (null)--import qualified Data.Sequence as SEQ--import qualified Data.ByteString as BS-import qualified Data.ByteString.Lazy as BSL--import qualified Data.Text as T-import qualified Data.Text.Lazy as TL--import qualified Data.HashMap.Strict as HM-import qualified Data.HashSet as HS-import qualified Data.IntMap as IM-import qualified Data.IntSet as IS-import qualified Data.Map as M-import qualified Data.Set as S--import qualified Data.Vector as V-import qualified Data.Vector.Primitive as VP-import qualified Data.Vector.Storable as VS-import qualified Data.Vector.Unboxed as VU--import Applicative (pass)--------------------------------------------------------------------------------- Containers (e.g. tuples aren't containers)--------------------------------------------------------------------------------- | Type of element for some container. Implemented as a type family because--- some containers are monomorphic over element type (like 'T.Text', 'IS.IntSet', etc.)--- so we can't implement nice interface using old higher-kinded types approach.-type family Element t--type instance Element (f a) = a-type instance Element T.Text = Char-type instance Element TL.Text = Char-type instance Element BS.ByteString = Word8-type instance Element BSL.ByteString = Word8-type instance Element IS.IntSet = Int---- | Type class for data types that can be converted to List.--- Fully compatible with 'Foldable'.--- Contains very small and safe subset of 'Foldable' functions.------ You can define 'Tolist' by just defining 'toList' function.--- But the following law should be met:------ @'null' ≡ 'List.null' . 'toList'@----class ToList t where- {-# MINIMAL toList #-}- -- | Convert container to list of elements.- --- -- >>> toList (Just True)- -- [True]- -- >>> toList @Text "aba"- -- "aba"- -- >>> :t toList @Text "aba"- -- toList @Text "aba" :: [Char]- toList :: t -> [Element t]-- -- | Checks whether container is empty.- --- -- >>> null @Text ""- -- True- -- >>> null @Text "aba"- -- False- null :: t -> Bool- null = List.null . toList---- | This instance makes 'ToList' compatible and overlappable by 'Foldable'.-instance {-# OVERLAPPABLE #-} Foldable f => ToList (f a) where- toList = F.toList- {-# INLINE toList #-}- null = F.null- {-# INLINE null #-}--instance ToList T.Text where- toList = T.unpack- {-# INLINE toList #-}- null = T.null- {-# INLINE null #-}--instance ToList TL.Text where- toList = TL.unpack- {-# INLINE toList #-}- null = TL.null- {-# INLINE null #-}--instance ToList BS.ByteString where- toList = BS.unpack- {-# INLINE toList #-}- null = BS.null- {-# INLINE null #-}--instance ToList BSL.ByteString where- toList = BSL.unpack- {-# INLINE toList #-}- null = BSL.null- {-# INLINE null #-}--instance ToList IS.IntSet where- toList = IS.toList- {-# INLINE toList #-}- null = IS.null- {-# INLINE null #-}--------------------------------------------------------------------------------- Additional operations that don't make much sense for e.g. Maybe--------------------------------------------------------------------------------- | A class for 'ToList's that aren't trivial like 'Maybe' (e.g. can hold--- more than one value)-class ToList t => Container t where- foldMap :: Monoid m => (Element t -> m) -> t -> m- foldMap f = foldr (mappend . f) mempty- {-# INLINE foldMap #-}-- fold :: Monoid (Element t) => t -> Element t- fold = foldMap id-- foldr :: (Element t -> b -> b) -> b -> t -> b- foldr' :: (Element t -> b -> b) -> b -> t -> b- foldr' f z0 xs = foldl f' id xs z0- where f' k x z = k $! f x z- foldl :: (b -> Element t -> b) -> b -> t -> b- foldl' :: (b -> Element t -> b) -> b -> t -> b- foldr1 :: (Element t -> Element t -> Element t) -> t -> Element t- foldr1 f xs =-#if __GLASGOW_HASKELL__ >= 800- fromMaybe (errorWithoutStackTrace "foldr1: empty structure")- (foldr mf Nothing xs)-#else- fromMaybe (error "foldr1: empty structure")- (foldr mf Nothing xs)-#endif- where- mf x m = Just (case m of- Nothing -> x- Just y -> f x y)- foldl1 :: (Element t -> Element t -> Element t) -> t -> Element t- foldl1 f xs =-#if __GLASGOW_HASKELL__ >= 800- fromMaybe (errorWithoutStackTrace "foldl1: empty structure")- (foldl mf Nothing xs)-#else- fromMaybe (error "foldl1: empty structure")- (foldl mf Nothing xs)-#endif- where- mf m y = Just (case m of- Nothing -> y- Just x -> f x y)-- length :: t -> Int-- 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-- all :: (Element t -> Bool) -> t -> Bool- all p = getAll #. foldMap (All #. p)- any :: (Element t -> Bool) -> t -> Bool- any p = getAny #. foldMap (Any #. p)-- and :: (Element t ~ Bool) => t -> Bool- and = getAll #. foldMap All- or :: (Element t ~ Bool) => t -> Bool- or = getAny #. foldMap Any-- find :: (Element t -> Bool) -> t -> Maybe (Element t)- find p = getFirst . foldMap (\ x -> First (if p x then Just x else Nothing))-- head :: t -> Maybe (Element t)- head = foldr (\x _ -> Just x) Nothing- {-# INLINE head #-}---- | To save backwards compatibility with previous naming.-type NontrivialContainer t = Container t--instance {-# OVERLAPPABLE #-} Foldable f => Container (f a) where- foldMap = F.foldMap- {-# INLINE foldMap #-}- fold = F.fold- {-# INLINE fold #-}- foldr = F.foldr- {-# INLINE foldr #-}- foldr' = F.foldr'- {-# INLINE foldr' #-}- foldl = F.foldl- {-# INLINE foldl #-}- foldl' = F.foldl'- {-# INLINE foldl' #-}- foldr1 = F.foldr1- {-# INLINE foldr1 #-}- foldl1 = F.foldl1- {-# INLINE foldl1 #-}- length = F.length- {-# INLINE length #-}- elem = F.elem- {-# INLINE elem #-}- notElem = F.notElem- {-# INLINE notElem #-}- maximum = F.maximum- {-# INLINE maximum #-}- minimum = F.minimum- {-# INLINE minimum #-}- all = F.all- {-# INLINE all #-}- any = F.any- {-# INLINE any #-}- and = F.and- {-# INLINE and #-}- or = F.or- {-# INLINE or #-}- find = F.find- {-# INLINE find #-}--instance Container T.Text where- foldr = T.foldr- {-# INLINE foldr #-}- foldl = T.foldl- {-# INLINE foldl #-}- foldl' = T.foldl'- {-# INLINE foldl' #-}- foldr1 = T.foldr1- {-# INLINE foldr1 #-}- foldl1 = T.foldl1- {-# INLINE foldl1 #-}- length = T.length- {-# INLINE length #-}- elem c = T.isInfixOf (T.singleton c) -- there are rewrite rules for this- {-# INLINE elem #-}- maximum = T.maximum- {-# INLINE maximum #-}- minimum = T.minimum- {-# INLINE minimum #-}- all = T.all- {-# INLINE all #-}- any = T.any- {-# INLINE any #-}- find = T.find- {-# INLINE find #-}- head = fmap fst . T.uncons- {-# INLINE head #-}--instance Container TL.Text where- foldr = TL.foldr- {-# INLINE foldr #-}- foldl = TL.foldl- {-# INLINE foldl #-}- foldl' = TL.foldl'- {-# INLINE foldl' #-}- foldr1 = TL.foldr1- {-# INLINE foldr1 #-}- foldl1 = TL.foldl1- {-# INLINE foldl1 #-}- length = fromIntegral . TL.length- {-# INLINE length #-}- -- will be okay thanks to rewrite rules- elem c s = TL.isInfixOf (TL.singleton c) s- {-# INLINE elem #-}- maximum = TL.maximum- {-# INLINE maximum #-}- minimum = TL.minimum- {-# INLINE minimum #-}- all = TL.all- {-# INLINE all #-}- any = TL.any- {-# INLINE any #-}- find = TL.find- {-# INLINE find #-}- head = fmap fst . TL.uncons- {-# INLINE head #-}--instance Container BS.ByteString where- foldr = BS.foldr- {-# INLINE foldr #-}- foldl = BS.foldl- {-# INLINE foldl #-}- foldl' = BS.foldl'- {-# INLINE foldl' #-}- foldr1 = BS.foldr1- {-# INLINE foldr1 #-}- foldl1 = BS.foldl1- {-# INLINE foldl1 #-}- length = BS.length- {-# INLINE length #-}- elem = BS.elem- {-# INLINE elem #-}- notElem = BS.notElem- {-# INLINE notElem #-}- maximum = BS.maximum- {-# INLINE maximum #-}- minimum = BS.minimum- {-# INLINE minimum #-}- all = BS.all- {-# INLINE all #-}- any = BS.any- {-# INLINE any #-}- find = BS.find- {-# INLINE find #-}- head = fmap fst . BS.uncons- {-# INLINE head #-}--instance Container BSL.ByteString where- foldr = BSL.foldr- {-# INLINE foldr #-}- foldl = BSL.foldl- {-# INLINE foldl #-}- foldl' = BSL.foldl'- {-# INLINE foldl' #-}- foldr1 = BSL.foldr1- {-# INLINE foldr1 #-}- foldl1 = BSL.foldl1- {-# INLINE foldl1 #-}- length = fromIntegral . BSL.length- {-# INLINE length #-}- elem = BSL.elem- {-# INLINE elem #-}- notElem = BSL.notElem- {-# INLINE notElem #-}- maximum = BSL.maximum- {-# INLINE maximum #-}- minimum = BSL.minimum- {-# INLINE minimum #-}- all = BSL.all- {-# INLINE all #-}- any = BSL.any- {-# INLINE any #-}- find = BSL.find- {-# INLINE find #-}- head = fmap fst . BSL.uncons- {-# INLINE head #-}--instance Container IS.IntSet where- foldr = IS.foldr- {-# INLINE foldr #-}- foldl = IS.foldl- {-# INLINE foldl #-}- foldl' = IS.foldl'- {-# INLINE foldl' #-}- length = IS.size- {-# INLINE length #-}- elem = IS.member- {-# INLINE elem #-}- maximum = IS.findMax- {-# INLINE maximum #-}- minimum = IS.findMin- {-# INLINE minimum #-}- head = fmap fst . IS.minView- {-# INLINE head #-}--------------------------------------------------------------------------------- Wrapped List-------------------------------------------------------------------------------- | This can be useful if you want to use 'Container' methods for your data type--- but you don't want to implement all methods of this type class for that.-newtype WrappedList f a = WrappedList (f a)--type instance Element (WrappedList f a) = a--instance ToList (f a) => ToList (WrappedList f a) where- toList (WrappedList l) = toList l- {-# INLINE toList #-}- null (WrappedList l) = null l- {-# INLINE null #-}--instance ToList (f a) => Container (WrappedList f a) where- foldMap f = foldMap f . toList- {-# INLINE foldMap #-}- fold = fold . toList- {-# INLINE fold #-}- foldr f z = foldr f z . toList- {-# INLINE foldr #-}- foldr' f z = foldr' f z . toList- {-# INLINE foldr' #-}- foldl f z = foldl f z . toList- {-# INLINE foldl #-}- foldl' f z = foldl' f z . toList- {-# INLINE foldl' #-}- foldr1 f = foldr1 f . toList- {-# INLINE foldr1 #-}- foldl1 f = foldl1 f . toList- {-# INLINE foldl1 #-}- length = length . toList- {-# INLINE length #-}- elem x = elem x . toList- {-# INLINE elem #-}- notElem x = notElem x . toList- {-# INLINE notElem #-}- maximum = maximum . toList- {-# INLINE maximum #-}- minimum = minimum . toList- {-# INLINE minimum #-}- all p = all p . toList- {-# INLINE all #-}- any p = any p . toList- {-# INLINE any #-}- and = and . toList- {-# INLINE and #-}- or = or . toList- {-# INLINE or #-}- find p = find p . toList- {-# INLINE find #-}- head = head . toList- {-# INLINE head #-}---------------------------------------------------------------------------------- Derivative functions--------------------------------------------------------------------------------- | Stricter version of 'Prelude.sum'.------ >>> sum [1..10]--- 55--- >>> sum (Just 3)--- <interactive>:43:1: error:--- • Do not use 'Foldable' methods on Maybe--- • In the expression: sum (Just 3)--- In an equation for ‘it’: it = sum (Just 3)-sum :: (Container t, Num (Element t)) => t -> Element t-sum = foldl' (+) 0---- | Stricter version of 'Prelude.product'.------ >>> product [1..10]--- 3628800--- >>> product (Right 3)--- <interactive>:45:1: error:--- • Do not use 'Foldable' methods on Either--- • In the expression: product (Right 3)--- In an equation for ‘it’: it = product (Right 3)-product :: (Container t, Num (Element t)) => t -> Element t-product = foldl' (*) 1---- | Constrained to 'Container' version of 'Data.Foldable.traverse_'.-traverse_- :: (Container t, Applicative f)- => (Element t -> f b) -> t -> f ()-traverse_ f = foldr ((*>) . f) pass---- | Constrained to 'Container' version of 'Data.Foldable.for_'.-for_- :: (Container t, Applicative f)- => t -> (Element t -> f b) -> f ()-for_ = flip traverse_-{-# INLINE for_ #-}---- | Constrained to 'Container' version of 'Data.Foldable.mapM_'.-mapM_- :: (Container t, Monad m)- => (Element t -> m b) -> t -> m ()-mapM_ f= foldr ((>>) . f) pass---- | Constrained to 'Container' version of 'Data.Foldable.forM_'.-forM_- :: (Container t, Monad m)- => t -> (Element t -> m b) -> m ()-forM_ = flip mapM_-{-# INLINE forM_ #-}---- | Constrained to 'Container' version of 'Data.Foldable.sequenceA_'.-sequenceA_- :: (Container t, Applicative f, Element t ~ f a)- => t -> f ()-sequenceA_ = foldr (*>) pass---- | Constrained to 'Container' version of 'Data.Foldable.sequence_'.-sequence_- :: (Container t, Monad m, Element t ~ m a)- => t -> m ()-sequence_ = foldr (>>) pass---- | Constrained to 'Container' version of 'Data.Foldable.asum'.-asum- :: (Container t, Alternative f, Element t ~ f a)- => t -> f a-asum = foldr (<|>) empty-{-# INLINE asum #-}--------------------------------------------------------------------------------- Disallowed instances-------------------------------------------------------------------------------#if __GLASGOW_HASKELL__ >= 800-type family DisallowInstance (z :: Symbol) :: ErrorMessage where- DisallowInstance z = Text "Do not use 'Foldable' methods on " :<>: Text z- :$$: Text "Suggestions:"- :$$: Text " Instead of"- :$$: Text " for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()"- :$$: Text " use"- :$$: Text " whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()"- :$$: Text " whenRight :: Applicative f => Either l r -> (r -> f ()) -> f ()"- :$$: Text ""- :$$: Text " Instead of"- :$$: Text " fold :: (Foldable t, Monoid m) => t m -> m"- :$$: Text " use"- :$$: Text " maybeToMonoid :: Monoid m => Maybe m -> m"- :$$: Text ""-#endif--#define DISALLOW_TO_LIST_8(t, z) \- instance TypeError (DisallowInstance z) => \- ToList (t) where { \- toList = undefined; \- null = undefined; } \--#define DISALLOW_CONTAINER_8(t, z) \- instance TypeError (DisallowInstance z) => \- Container (t) where { \- foldr = undefined; \- foldl = undefined; \- foldl' = undefined; \- length = undefined; \- elem = undefined; \- maximum = undefined; \- minimum = undefined; } \--#define DISALLOW_TO_LIST_7(t) \- instance ForbiddenFoldable (t) => ToList (t) where { \- toList = undefined; \- null = undefined; } \--#define DISALLOW_CONTAINER_7(t) \- instance ForbiddenFoldable (t) => Container (t) where { \- foldr = undefined; \- foldl = undefined; \- foldl' = undefined; \- length = undefined; \- elem = undefined; \- maximum = undefined; \- minimum = undefined; } \--#if __GLASGOW_HASKELL__ >= 800-DISALLOW_TO_LIST_8((a, b),"tuples")-DISALLOW_CONTAINER_8((a, b),"tuples")-DISALLOW_CONTAINER_8(Maybe a,"Maybe")-DISALLOW_CONTAINER_8(Identity a,"Identity")-DISALLOW_CONTAINER_8(Either a b,"Either")-#else-class ForbiddenFoldable a-DISALLOW_TO_LIST_7((a, b))-DISALLOW_CONTAINER_7((a, b))-DISALLOW_CONTAINER_7(Maybe a)-DISALLOW_CONTAINER_7(Identity a)-DISALLOW_CONTAINER_7(Either a b)-#endif--------------------------------------------------------------------------------- One--------------------------------------------------------------------------------- | Type class for types that can be created from one element. @singleton@--- is lone name for this function. Also constructions of different type differ:--- @:[]@ for lists, two arguments for Maps. Also some data types are monomorphic.------ >>> one True :: [Bool]--- [True]--- >>> one 'a' :: Text--- "a"--- >>> one (3, "hello") :: HashMap Int String--- fromList [(3,"hello")]-class One x where- type OneItem x- -- | Create a list, map, 'Text', etc from a single element.- one :: OneItem x -> x---- Lists--instance One [a] where- type OneItem [a] = a- one = (:[])- {-# INLINE one #-}--#if ( __GLASGOW_HASKELL__ >= 800 )-instance One (NE.NonEmpty a) where- type OneItem (NE.NonEmpty a) = a- one = (NE.:|[])- {-# INLINE one #-}-#endif--instance One (SEQ.Seq a) where- type OneItem (SEQ.Seq a) = a- one = (SEQ.empty SEQ.|>)- {-# INLINE one #-}---- Monomorphic sequences--instance One T.Text where- type OneItem T.Text = Char- one = T.singleton- {-# INLINE one #-}--instance One TL.Text where- type OneItem TL.Text = Char- one = TL.singleton- {-# INLINE one #-}--instance One BS.ByteString where- type OneItem BS.ByteString = Word8- one = BS.singleton- {-# INLINE one #-}--instance One BSL.ByteString where- type OneItem BSL.ByteString = Word8- one = BSL.singleton- {-# INLINE one #-}---- Maps--instance One (M.Map k v) where- type OneItem (M.Map k v) = (k, v)- one = uncurry M.singleton- {-# INLINE one #-}--instance Hashable k => One (HM.HashMap k v) where- type OneItem (HM.HashMap k v) = (k, v)- one = uncurry HM.singleton- {-# INLINE one #-}--instance One (IM.IntMap v) where- type OneItem (IM.IntMap v) = (Int, v)- one = uncurry IM.singleton- {-# INLINE one #-}---- Sets--instance One (S.Set v) where- type OneItem (S.Set v) = v- one = S.singleton- {-# INLINE one #-}--instance Hashable v => One (HS.HashSet v) where- type OneItem (HS.HashSet v) = v- one = HS.singleton- {-# INLINE one #-}--instance One IS.IntSet where- type OneItem IS.IntSet = Int- one = IS.singleton- {-# INLINE one #-}---- Vectors--instance One (V.Vector a) where- type OneItem (V.Vector a) = a- one = V.singleton- {-# INLINE one #-}--instance VU.Unbox a => One (VU.Vector a) where- type OneItem (VU.Vector a) = a- one = VU.singleton- {-# INLINE one #-}--instance VP.Prim a => One (VP.Vector a) where- type OneItem (VP.Vector a) = a- one = VP.singleton- {-# INLINE one #-}--instance VS.Storable a => One (VS.Vector a) where- type OneItem (VS.Vector a) = a- one = VS.singleton- {-# INLINE one #-}--------------------------------------------------------------------------------- Utils-------------------------------------------------------------------------------(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)-(#.) _f = coerce-{-# INLINE (#.) #-}
− src/Container/Reexport.hs
@@ -1,23 +0,0 @@--- | This module reexports all container related stuff from 'Prelude'.--module Container.Reexport- ( module Data.Hashable- , module Data.HashMap.Strict- , module Data.HashSet- , module Data.IntMap.Strict- , module Data.IntSet- , module Data.Map.Strict- , module Data.Sequence- , module Data.Set- , module Data.Vector- ) where--import Data.Hashable (Hashable)-import Data.HashMap.Strict (HashMap)-import Data.HashSet (HashSet)-import Data.IntMap.Strict (IntMap)-import Data.IntSet (IntSet)-import Data.Map.Strict (Map)-import Data.Sequence (Seq)-import Data.Set (Set)-import Data.Vector (Vector)
− src/Debug.hs
@@ -1,78 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE Trustworthy #-}---- | Functions for debugging. If you left these functions in your code--- then warning is generated to remind you about left usages. Also some--- functions (and data types) are convenient for prototyping.--module Debug- ( undefined- , error- , trace- , traceM- , traceId- , traceShow- , traceShowId- , traceShowM- , Undefined (..)- ) where--import Control.Monad (Monad, return)-import Data.Data (Data)-import Data.Text (Text, unpack)-import Data.Typeable (Typeable)-import GHC.Generics (Generic)-import System.IO.Unsafe (unsafePerformIO)--import qualified Base as P-import qualified Prelude as P-import Print (Print, putStrLn)--import Applicative (pass)---- | Generalized over string version of 'Debug.Trace.trace' that leaves warnings.-{-# WARNING trace "'trace' remains in code" #-}-trace :: Print b => b -> a -> a-trace string expr = unsafePerformIO (do- putStrLn string- return expr)---- | 'P.error' that takes 'Text' as an argument.-error :: Text -> a-error s = P.error (unpack s)---- | Version of 'Debug.Trace.traceShow' that leaves warning.-{-# WARNING traceShow "'traceShow' remains in code" #-}-traceShow :: P.Show a => a -> b -> b-traceShow a b = trace (P.show a) b---- | Version of 'Debug.Trace.traceShow' that leaves warning.-{-# WARNING traceShowId "'traceShowId' remains in code" #-}-traceShowId :: P.Show a => a -> a-traceShowId a = trace (P.show a) a---- | Version of 'Debug.Trace.traceShowM' that leaves warning.-{-# WARNING traceShowM "'traceShowM' remains in code" #-}-traceShowM :: (P.Show a, Monad m) => a -> m ()-traceShowM a = trace (P.show a) pass---- | Version of 'Debug.Trace.traceM' that leaves warning and takes 'Text'.-{-# WARNING traceM "'traceM' remains in code" #-}-traceM :: (Monad m) => Text -> m ()-traceM s = trace (unpack s) pass---- | Version of 'Debug.Trace.traceId' that leaves warning and takes 'Text'.-{-# WARNING traceId "'traceId' remains in code" #-}-traceId :: Text -> Text-traceId s = trace s s---- | Similar to 'undefined' but data type.-{-# WARNING Undefined "'Undefined' type remains in code" #-}-data Undefined = Undefined- deriving (P.Eq, P.Ord, P.Show, P.Read, P.Enum, P.Bounded, Data, Typeable, Generic)---- | 'P.undefined' that leaves warning in code on every usage.-{-# WARNING undefined "'undefined' function remains in code (or use 'error')" #-}-undefined :: a-undefined = P.undefined
− src/Exceptions.hs
@@ -1,60 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE Safe #-}---- | Re-exports most useful functionality from 'safe-exceptions'. Also--- provides some functions to work with exceptions over 'MonadError'.--module Exceptions- ( module Control.Exception.Safe--#if ( __GLASGOW_HASKELL__ >= 800 )- , Bug (..)- , bug-#endif- , note- ) where---- exceptions from safe-exceptions-import Control.Exception.Safe (Exception (..), MonadCatch, MonadMask (..), MonadThrow,- SomeException (..), bracket, bracketOnError, bracket_, catch,- catchAny, displayException, finally, handleAny, mask_, onException,- throwM, try, tryAny)--import Control.Applicative (Applicative (pure))-import Control.Monad.Except (MonadError, throwError)-import Data.Maybe (Maybe, maybe)--#if ( __GLASGOW_HASKELL__ >= 800 )-import Data.List ((++))-import GHC.Show (Show)-import GHC.Stack (CallStack, HasCallStack, callStack, prettyCallStack)--import qualified Control.Exception.Safe as Safe (impureThrow, toException)---- | Type that represents exceptions used in cases when a particular codepath--- is not meant to be ever executed, but happens to be executed anyway.-data Bug = Bug SomeException CallStack- deriving (Show)--instance Exception Bug where- displayException (Bug e cStack) = displayException e ++ "\n"- ++ prettyCallStack cStack---- | Generate a pure value which, when forced, will synchronously--- throw the exception wrapped into 'Bug' data type.-bug :: (HasCallStack, Exception e) => e -> a-bug e = Safe.impureThrow (Bug (Safe.toException e) callStack)-#endif----- To suppress redundant applicative constraint warning on GHC 8.0--- | Throws error for 'Maybe' if 'Data.Maybe.Nothing' is given.--- Operates over 'MonadError'.-#if ( __GLASGOW_HASKELL__ >= 800 )-note :: (MonadError e m) => e -> Maybe a -> m a-note err = maybe (throwError err) pure-#else-note :: (MonadError e m, Applicative m) => e -> Maybe a -> m a-note err = maybe (throwError err) pure-#endif
− src/Functor.hs
@@ -1,23 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE Safe #-}---- | Convenient functions to work with 'Functor'.--module Functor- ( Functor (..)- , void- , ($>)- , (<$>)- , (<<$>>)- ) where--import Data.Function ((.))-import Data.Functor (Functor (..), void, ($>), (<$>))---- | Alias for @fmap . fmap@. Convenient to work with two nested 'Functor's.------ >>> negate <<$>> Just [1,2,3]--- Just [-1,-2,-3]-(<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)-(<<$>>) = fmap . fmap-infixl 4 <<$>>
− src/Lifted.hs
@@ -1,25 +0,0 @@-{-# LANGUAGE Safe #-}---- | Lifted versions of base functions.--module Lifted- ( module Lifted.Concurrent- , module Lifted.Env- , module Lifted.File- , module Lifted.IORef-- , stToIO- ) where--import Lifted.Concurrent-import Lifted.Env-import Lifted.File-import Lifted.IORef--import qualified Control.Monad.ST as XIO-import Control.Monad.Trans (MonadIO, liftIO)---- | Lifted version of 'XIO.stToIO'.-stToIO :: MonadIO m => XIO.ST XIO.RealWorld a -> m a-stToIO a = liftIO (XIO.stToIO a)-{-# INLINE stToIO #-}
− src/Lifted/Concurrent.hs
@@ -1,112 +0,0 @@-{-# LANGUAGE Safe #-}---- | Concurrency useful and common functions.--module Lifted.Concurrent- ( -- * MVar- MVar- , newEmptyMVar- , newMVar- , putMVar- , readMVar- , swapMVar- , takeMVar- , tryPutMVar- , tryReadMVar- , tryTakeMVar-- -- * STM- , STM- , TVar- , atomically- , newTVarIO- , readTVarIO- , STM.modifyTVar'- , STM.newTVar- , STM.readTVar- , STM.writeTVar- ) where---import qualified Control.Concurrent.MVar as CCM (newEmptyMVar, newMVar, putMVar,- readMVar, swapMVar, takeMVar,- tryPutMVar, tryReadMVar, tryTakeMVar)-import qualified Control.Concurrent.STM.TVar as STM (modifyTVar', newTVar, newTVarIO,- readTVar, readTVarIO, writeTVar)-import qualified Control.Monad.STM as STM (atomically)--import Control.Concurrent.MVar (MVar)-import Control.Concurrent.STM.TVar (TVar)-import Control.Monad.STM (STM)-import Control.Monad.Trans (MonadIO, liftIO)-import Data.Bool (Bool)-import Data.Function (($), (.))-import Data.Maybe (Maybe)--------------------------------------------------------------------------------- Lifted Control.Concurrent.MVar--------------------------------------------------------------------------------- | Lifted to 'MonadIO' version of 'CCM.newEmptyMVar'.-newEmptyMVar :: MonadIO m => m (MVar a)-newEmptyMVar = liftIO CCM.newEmptyMVar-{-# INLINE newEmptyMVar #-}---- | Lifted to 'MonadIO' version of 'CCM.newMVar'.-newMVar :: MonadIO m => a -> m (MVar a)-newMVar = liftIO . CCM.newMVar-{-# INLINE newMVar #-}---- | Lifted to 'MonadIO' version of 'CCM.putMVar'.-putMVar :: MonadIO m => MVar a -> a -> m ()-putMVar m a = liftIO $ CCM.putMVar m a-{-# INLINE putMVar #-}---- | Lifted to 'MonadIO' version of 'CCM.readMVar'.-readMVar :: MonadIO m => MVar a -> m a-readMVar = liftIO . CCM.readMVar-{-# INLINE readMVar #-}---- | Lifted to 'MonadIO' version of 'CCM.swapMVar'.-swapMVar :: MonadIO m => MVar a -> a -> m a-swapMVar m v = liftIO $ CCM.swapMVar m v-{-# INLINE swapMVar #-}---- | Lifted to 'MonadIO' version of 'CCM.takeMVar'.-takeMVar :: MonadIO m => MVar a -> m a-takeMVar = liftIO . CCM.takeMVar-{-# INLINE takeMVar #-}---- | Lifted to 'MonadIO' version of 'CCM.tryPutMVar'.-tryPutMVar :: MonadIO m => MVar a -> a -> m Bool-tryPutMVar m v = liftIO $ CCM.tryPutMVar m v-{-# INLINE tryPutMVar #-}---- | Lifted to 'MonadIO' version of 'CCM.tryReadMVar'.-tryReadMVar :: MonadIO m => MVar a -> m (Maybe a)-tryReadMVar = liftIO . CCM.tryReadMVar-{-# INLINE tryReadMVar #-}---- | Lifted to 'MonadIO' version of 'CCM.tryTakeMVar'.-tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a)-tryTakeMVar = liftIO . CCM.tryTakeMVar-{-# INLINE tryTakeMVar #-}--------------------------------------------------------------------------------- Lifted STM--------------------------------------------------------------------------------- | Lifted to 'MonadIO' version of 'STM.atomically'.-atomically :: MonadIO m => STM a -> m a-atomically = liftIO . STM.atomically-{-# INLINE atomically #-}---- | Lifted to 'MonadIO' version of 'STM.newTVarIO'.-newTVarIO :: MonadIO m => a -> m (TVar a)-newTVarIO = liftIO . STM.newTVarIO-{-# INLINE newTVarIO #-}---- | Lifted to 'MonadIO' version of 'STM.readTVarIO'.-readTVarIO :: MonadIO m => TVar a -> m a-readTVarIO = liftIO . STM.readTVarIO-{-# INLINE readTVarIO #-}
− src/Lifted/Env.hs
@@ -1,47 +0,0 @@-{-# LANGUAGE Safe #-}---- | Lifted versions of functions that work with environment.--module Lifted.Env- ( getArgs- , exitWith- , exitFailure- , exitSuccess- , die- ) where--import Control.Monad.Trans (MonadIO, liftIO)-import Data.String (String)-import Prelude ((>>))-import qualified System.Environment as XIO-import System.Exit (ExitCode)-import qualified System.Exit as XIO-import System.IO (stderr)-import qualified System.IO (hPutStrLn)---- | Lifted version of 'System.Environment.getArgs'.-getArgs :: MonadIO m => m [String]-getArgs = liftIO (XIO.getArgs)-{-# INLINE getArgs #-}---- | Lifted version of 'System.Exit.exitWith'.-exitWith :: MonadIO m => ExitCode -> m a-exitWith a = liftIO (XIO.exitWith a)-{-# INLINE exitWith #-}---- | Lifted version of 'System.Exit.exitFailure'.-exitFailure :: MonadIO m => m a-exitFailure = liftIO XIO.exitFailure-{-# INLINE exitFailure #-}---- | Lifted version of 'System.Exit.exitSuccess'.-exitSuccess :: MonadIO m => m a-exitSuccess = liftIO XIO.exitSuccess-{-# INLINE exitSuccess #-}---- | Lifted version of 'System.Exit.die'.--- 'XIO.die' is available since base-4.8, but it's more convenient to--- redefine it instead of using CPP.-die :: MonadIO m => String -> m ()-die err = liftIO (System.IO.hPutStrLn stderr err) >> exitFailure-{-# INLINE die #-}
− src/Lifted/File.hs
@@ -1,65 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE Safe #-}---- | Lifted versions of functions working with files and common IO.--- All functions are specialized to 'Data.Text.Text'.--module Lifted.File- ( appendFile- , getContents- , getLine- , interact- , openFile- , readFile- , writeFile- ) where--import Control.Monad.Trans (MonadIO, liftIO)-import Data.Text (Text)-import qualified Data.Text.IO as XIO-import qualified Data.Text.Lazy as L (Text)-import qualified Data.Text.Lazy.IO as LIO (getContents, interact)-import Prelude (FilePath)-import System.IO (Handle, IOMode)-import qualified System.IO as XIO (openFile)--------------------------------------------------------------------------------- Text--------------------------------------------------------------------------------- | Lifted version of 'Data.Text.appendFile'.-appendFile :: MonadIO m => FilePath -> Text -> m ()-appendFile a b = liftIO (XIO.appendFile a b)-{-# INLINE appendFile #-}---- | Lifted version of 'Data.Text.getContents'.-getContents :: MonadIO m => m L.Text-getContents = liftIO LIO.getContents-{-# INLINE getContents #-}---- | Lifted version of 'Data.Text.getLine'.-getLine :: MonadIO m => m Text-getLine = liftIO XIO.getLine-{-# INLINE getLine #-}---- | Lifted version of 'Data.Text.interact'.-interact :: MonadIO m => (L.Text -> L.Text) -> m ()-interact a = liftIO (LIO.interact a)-{-# INLINE interact #-}---- | Lifted version of 'Data.Text.readFile'.-readFile :: MonadIO m => FilePath -> m Text-readFile a = liftIO (XIO.readFile a)-{-# INLINE readFile #-}---- | Lifted version of 'Data.Text.writeFile'.-writeFile :: MonadIO m => FilePath -> Text -> m ()-writeFile a b = liftIO (XIO.writeFile a b)-{-# INLINE writeFile #-}---- | Lifted version of 'System.IO.openFile'.-openFile :: MonadIO m => FilePath -> IOMode -> m Handle-openFile a b = liftIO (XIO.openFile a b)-{-# INLINE openFile #-}---- 'withFile' can't be lifted into 'MonadIO', as it uses 'bracket'
− src/Lifted/IORef.hs
@@ -1,63 +0,0 @@-{-# LANGUAGE Safe #-}---- | Lifted reexports from 'Data.IORef' module.--module Lifted.IORef- ( IORef- , atomicModifyIORef- , atomicModifyIORef'- , atomicWriteIORef- , modifyIORef- , modifyIORef'- , newIORef- , readIORef- , writeIORef- ) where--import qualified Data.IORef as Ref (atomicModifyIORef, atomicModifyIORef',- atomicWriteIORef, modifyIORef, modifyIORef',- newIORef, readIORef, writeIORef)--import Control.Monad.Trans (MonadIO, liftIO)-import Data.Function (($), (.))-import Data.IORef (IORef)---- | Lifted version of 'Ref.newIORef'.-newIORef :: MonadIO m => a -> m (IORef a)-newIORef = liftIO . Ref.newIORef-{-# INLINE newIORef #-}---- | Lifted version of 'Ref.readIORef'.-readIORef :: MonadIO m => IORef a -> m a-readIORef = liftIO . Ref.readIORef-{-# INLINE readIORef #-}---- | Lifted version of 'Ref.writeIORef'.-writeIORef :: MonadIO m => IORef a -> a -> m ()-writeIORef ref what = liftIO $ Ref.writeIORef ref what-{-# INLINE writeIORef #-}---- | Lifted version of 'Ref.modifyIORef'.-modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()-modifyIORef ref how = liftIO $ Ref.modifyIORef ref how-{-# INLINE modifyIORef #-}---- | Lifted version of 'Ref.modifyIORef''.-modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()-modifyIORef' ref how = liftIO $ Ref.modifyIORef' ref how-{-# INLINE modifyIORef' #-}---- | Lifted version of 'Ref.atomicModifyIORef'.-atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b-atomicModifyIORef ref how = liftIO $ Ref.atomicModifyIORef ref how-{-# INLINE atomicModifyIORef #-}---- | Lifted version of 'Ref.atomicModifyIORef''.-atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b-atomicModifyIORef' ref how = liftIO $ Ref.atomicModifyIORef' ref how-{-# INLINE atomicModifyIORef' #-}---- | Lifted version of 'Ref.atomicWriteIORef'.-atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()-atomicWriteIORef ref what = liftIO $ Ref.atomicWriteIORef ref what-{-# INLINE atomicWriteIORef #-}
− src/List.hs
@@ -1,60 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE Trustworthy #-}---- | Utility functions to work with lists.--module List- ( module Data.List-- , list- , sortWith-#if ( __GLASGOW_HASKELL__ >= 800 )- , whenNotNull- , whenNotNullM-#endif- ) 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.Functor (fmap)-import GHC.Exts (sortWith)--#if ( __GLASGOW_HASKELL__ >= 800 )-import Control.Applicative (Applicative)-import Control.Monad (Monad (..))-import Data.List.NonEmpty as X (NonEmpty (..))--import Applicative (pass)-#endif---- | Returns default list if given list is empty.--- Otherwise applies given function to every element.------ >>> list [True] even []--- [True]--- >>> list [True] even [1..5]--- [False,True,False,True,False]-list :: [b] -> (a -> b) -> [a] -> [b]-list def f xs = case xs of- [] -> def- _ -> fmap f xs--#if ( __GLASGOW_HASKELL__ >= 800 )--- | Performs given action over 'NonEmpty' list if given list is non empty.-whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()-whenNotNull [] _ = pass-whenNotNull (x:xs) f = f (x :| xs)-{-# INLINE whenNotNull #-}---- | Monadic version of 'whenNotNull'.-whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m ()-whenNotNullM ml f = ml >>= \l -> whenNotNull l f-{-# INLINE whenNotNullM #-}-#endif
− src/Monad.hs
@@ -1,227 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE TypeFamilies #-}---- | Reexporting useful monadic stuff.--module Monad- ( module Monad.Maybe- , module Monad.Either- , module Monad.Trans-- , Monad ((>>=), (>>), return)- , MonadFail (fail)- , MonadPlus (..)-- , (=<<)- , (>=>)- , (<=<)- , forever-- , join- , mfilter- , filterM- , mapAndUnzipM- , zipWithM- , zipWithM_- , foldM- , foldM_- , replicateM- , replicateM_-- , concatMapM- , concatForM-- , allM- , anyM- , andM- , orM-- , liftM- , liftM2- , liftM3- , liftM4- , liftM5- , ap-- , (<$!>)- ) where--import Monad.Either-import Monad.Maybe-import Monad.Trans--import Base (IO, seq)-import Control.Applicative (Applicative (pure))-import Data.Function ((.))-import Data.Functor (fmap)-import Data.Traversable (Traversable (traverse))-import Prelude (Bool (..), Monoid, flip)--#if __GLASGOW_HASKELL__ >= 710-import Control.Monad hiding (fail, (<$!>))-#else-import Control.Monad hiding (fail)-#endif--#if __GLASGOW_HASKELL__ >= 800-import Control.Monad.Fail (MonadFail (..))-#else-import Prelude (Maybe (Nothing), String)-import Text.ParserCombinators.ReadP (ReadP)-import Text.ParserCombinators.ReadPrec (ReadPrec)--import qualified Prelude as P (fail)-#endif--import Container (Container, Element, fold, toList)---- | Lifting bind into a monad. Generalized version of @concatMap@--- that works with a monadic predicate. Old and simpler specialized to list--- version had next type:------ @--- concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b]--- @------ Side note: previously it had type------ @--- concatMapM :: (Applicative q, Monad m, Traversable m)--- => (a -> q (m b)) -> m a -> q (m b)--- @------ Such signature didn't allow to use this function when traversed container--- type and type of returned by function-argument differed.--- Now you can use it like e.g.------ @--- concatMapM readFile files >>= putStrLn--- @-concatMapM- :: ( Applicative f- , Monoid m- , Container (l m)- , Traversable l- )- => (a -> f m) -> l a -> f m-concatMapM f = fmap fold . traverse f-{-# INLINE concatMapM #-}---- | Like 'concatMapM', but has its arguments flipped, so can be used--- instead of the common @fmap concat $ forM@ pattern.-concatForM- :: ( Applicative f- , Monoid m- , Container (l m)- , Traversable l- )- => l a -> (a -> f m) -> f m-concatForM = flip concatMapM-{-# INLINE concatForM #-}---- | Stricter version of 'Data.Functor.<$>'.-(<$!>) :: Monad m => (a -> b) -> m a -> m b-f <$!> m = do- x <- m- let z = f x- z `seq` return z-{-# INLINE (<$!>) #-}---- | Monadic and constrained to 'Container' version of 'Prelude.and'.------ >>> andM [Just True, Just False]--- Just False--- >>> andM [Just True]--- Just True--- >>> andM [Just True, Just False, Nothing]--- Just False--- >>> andM [Just True, Nothing]--- Nothing--- >>> andM [putStrLn "1" >> pure True, putStrLn "2" >> pure False, putStrLn "3" >> undefined]--- 1--- 2--- False-andM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool-andM = go . toList- where- go [] = pure True- go (p:ps) = do- q <- p- if q then go ps else pure False---- | Monadic and constrained to 'Container' version of 'Prelude.or'.------ >>> orM [Just True, Just False]--- Just True--- >>> orM [Just True, Nothing]--- Just True--- >>> orM [Nothing, Just True]--- Nothing-orM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool-orM = go . toList- where- go [] = pure False- go (p:ps) = do- q <- p- if q then pure True else go ps---- | Monadic and constrained to 'Container' version of 'Prelude.all'.------ >>> allM (readMaybe >=> pure . even) ["6", "10"]--- Just True--- >>> allM (readMaybe >=> pure . even) ["5", "aba"]--- Just False--- >>> allM (readMaybe >=> pure . even) ["aba", "10"]--- Nothing-allM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool-allM p = go . toList- where- go [] = pure True- go (x:xs) = do- q <- p x- if q then go xs else pure False---- | Monadic and constrained to 'Container' version of 'Prelude.any'.------ >>> anyM (readMaybe >=> pure . even) ["5", "10"]--- Just True--- >>> anyM (readMaybe >=> pure . even) ["10", "aba"]--- Just True--- >>> anyM (readMaybe >=> pure . even) ["aba", "10"]--- Nothing-anyM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool-anyM p = go . toList- where- go [] = pure False- go (x:xs) = do- q <- p x- if q then pure True else go xs--{-# SPECIALIZE andM :: [IO Bool] -> IO Bool #-}-{-# SPECIALIZE orM :: [IO Bool] -> IO Bool #-}-{-# SPECIALIZE anyM :: (a -> IO Bool) -> [a] -> IO Bool #-}-{-# SPECIALIZE allM :: (a -> IO Bool) -> [a] -> IO Bool #-}---#if __GLASGOW_HASKELL__ < 800--- | Class for 'Monad's that can 'fail'.--- Copied from 'fail' by Herbert Valerio Riedel (the library is under BSD3).-class Monad m => MonadFail m where- fail :: String -> m a--instance MonadFail Maybe where- fail _ = Nothing--instance MonadFail [] where- fail _ = []--instance MonadFail IO where- fail = P.fail--instance MonadFail ReadPrec where- fail = P.fail -- = P (\_ -> fail s)--instance MonadFail ReadP where- fail = P.fail-#endif
− src/Monad/Either.hs
@@ -1,105 +0,0 @@-{-# LANGUAGE Safe #-}---- | Utilites to work with @Either@ data type.--module Monad.Either- ( module Data.Either- , fromLeft- , fromRight- , maybeToLeft- , maybeToRight- , leftToMaybe- , rightToMaybe- , whenLeft- , whenLeftM- , whenRight- , whenRightM- ) where--import Control.Applicative (Applicative)-import Control.Monad (Monad (..))-import Data.Either (Either (..), either, isLeft, isRight, lefts,- partitionEithers, rights)-import Data.Function (const)-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)--- Just True--- >>> leftToMaybe (Right "aba")--- Nothing-leftToMaybe :: Either l r -> Maybe l-leftToMaybe = either Just (const Nothing)---- | Maps right part of 'Either' to 'Maybe'.------ >>> rightToMaybe (Left True)--- Nothing--- >>> leftToMaybe (Right "aba")--- Just "aba"-rightToMaybe :: Either l r -> Maybe r-rightToMaybe = either (const Nothing) Just---- | Maps 'Maybe' to 'Either' wrapping default value into 'Left'.------ >>> maybeToRight True (Just "aba")--- Right "aba"--- >>> maybeToRight True Nothing--- Left True-maybeToRight :: l -> Maybe r -> Either l r-maybeToRight l = maybe (Left l) Right---- | Maps 'Maybe' to 'Either' wrapping default value into 'Right'.------ >>> maybeToLeft True (Just "aba")--- Left "aba"--- >>> maybeToRight True Nothing--- Right True-maybeToLeft :: r -> Maybe l -> Either l r-maybeToLeft r = maybe (Right r) Left---- | Applies given action to 'Either' content if 'Left' is given.-whenLeft :: Applicative f => Either l r -> (l -> f ()) -> f ()-whenLeft (Left l) f = f l-whenLeft (Right _) _ = pass-{-# INLINE whenLeft #-}---- | Monadic version of 'whenLeft'.-whenLeftM :: Monad m => m (Either l r) -> (l -> m ()) -> m ()-whenLeftM me f = me >>= \e -> whenLeft e f-{-# INLINE whenLeftM #-}---- | Applies given action to 'Either' content if 'Right' is given.-whenRight :: Applicative f => Either l r -> (r -> f ()) -> f ()-whenRight (Left _) _ = pass-whenRight (Right r) f = f r-{-# INLINE whenRight #-}---- | Monadic version of 'whenRight'.-whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m ()-whenRightM me f = me >>= \e -> whenRight e f-{-# INLINE whenRightM #-}
− src/Monad/Maybe.hs
@@ -1,79 +0,0 @@-{-# LANGUAGE Safe #-}---- | Utility functions to work with 'Data.Maybe' data type as monad.--module Monad.Maybe- ( module Data.Maybe-- , maybeToMonoid- , whenJust- , whenJustM- , whenNothing- , whenNothing_- , whenNothingM- , whenNothingM_- ) where--import Data.Maybe (Maybe (..), catMaybes, fromMaybe, isJust, isNothing,- mapMaybe, maybe, maybeToList)--import Control.Applicative (Applicative, pure)-import Control.Monad (Monad (..))-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>.-whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()-whenJust (Just x) f = f x-whenJust Nothing _ = pass-{-# INLINE whenJust #-}---- | Monadic version of 'whenJust'.-whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()-whenJustM mm f = mm >>= \m -> whenJust m f-{-# INLINE whenJustM #-}---- | Performs default 'Applicative' action if 'Nothing' is given.--- Otherwise returns content of 'Just' pured to 'Applicative'.------ >>> whenNothing Nothing [True, False]--- [True,False]--- >>> whenNothing (Just True) [True, False]--- [True]-whenNothing :: Applicative f => Maybe a -> f a -> f a-whenNothing (Just x) _ = pure x-whenNothing Nothing m = m-{-# INLINE whenNothing #-}---- | Performs default 'Applicative' action if 'Nothing' is given.--- Do nothing for 'Just'. Convenient for discarding 'Just' content.------ >>> whenNothing_ Nothing $ putText "Nothing!"--- Nothing!--- >>> whenNothing_ (Just True) $ putText "Nothing!"-whenNothing_ :: Applicative f => Maybe a -> f () -> f ()-whenNothing_ Nothing m = m-whenNothing_ _ _ = pass-{-# INLINE whenNothing_ #-}---- | Monadic version of 'whenNothing'.-whenNothingM :: Monad m => m (Maybe a) -> m a -> m a-whenNothingM mm action = mm >>= \m -> whenNothing m action-{-# INLINE whenNothingM #-}---- | Monadic version of 'whenNothingM_'.-whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m ()-whenNothingM_ mm action = mm >>= \m -> whenNothing_ m action-{-# INLINE whenNothingM_ #-}
− src/Monad/Trans.hs
@@ -1,84 +0,0 @@-{-# LANGUAGE Safe #-}---- | Monad transformers utilities.--module Monad.Trans- ( -- * Reexports from @Control.Monad.*@- module Control.Monad.Except- , 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- , usingReader- , usingReaderT-- -- * Convenient functions to work with 'State' monad- , evaluatingState- , evaluatingStateT- , executingState- , executingStateT- , usingState- , usingStateT- ) 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, get,- gets, modify, 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, (<$>))---- | Shorter and more readable alias for @flip runReaderT@.-usingReaderT :: r -> ReaderT r m a -> m a-usingReaderT = flip runReaderT-{-# INLINE usingReaderT #-}---- | Shorter and more readable alias for @flip runReader@.-usingReader :: r -> Reader r a -> a-usingReader = flip runReader-{-# INLINE usingReader #-}---- | Shorter and more readable alias for @flip runStateT@.-usingStateT :: s -> StateT s m a -> m (a, s)-usingStateT = flip runStateT-{-# INLINE usingStateT #-}---- | Shorter and more readable alias for @flip runState@.-usingState :: s -> State s a -> (a, s)-usingState = flip runState-{-# INLINE usingState #-}---- | Alias for @flip evalStateT@. It's not shorter but sometimes--- more readable. Done by analogy with @using*@ functions family.-evaluatingStateT :: Functor f => s -> StateT s f a -> f a-evaluatingStateT s st = fst <$> usingStateT s st-{-# INLINE evaluatingStateT #-}---- | Alias for @flip evalState@. It's not shorter but sometimes--- more readable. Done by analogy with @using*@ functions family.-evaluatingState :: s -> State s a -> a-evaluatingState s st = fst (usingState s st)-{-# INLINE evaluatingState #-}---- | Alias for @flip execStateT@. It's not shorter but sometimes--- more readable. Done by analogy with @using*@ functions family.-executingStateT :: Functor f => s -> StateT s f a -> f s-executingStateT s st = snd <$> usingStateT s st-{-# INLINE executingStateT #-}---- | Alias for @flip execState@. It's not shorter but sometimes--- more readable. Done by analogy with @using*@ functions family.-executingState :: s -> State s a -> s-executingState s st = snd (usingState s st)-{-# INLINE executingState #-}
− src/Nub.hs
@@ -1,76 +0,0 @@-{-| Functions to remove duplicates from a list.-- = Performance- To check the performance there was done a bunch of benchmarks.- Benchmarks were made on lists of 'Prelude.Int's and 'Data.Text.Text's.- There were two types of list to use:-- * Lists which consist of many different elements-- * Lists which consist of many same elements--- Here are some recomendations for usage of particular functions based on benchmarking resutls.-- * 'hashNub' is faster than 'ordNub' when there're not so many different values in the list.-- * 'hashNub' is the fastest with 'Data.Text.Text'.-- * 'sortNub' has better performance than 'ordNub' but should be used when sorting is also needed.-- * 'unstableNub' has better performance than 'hashNub' but doesn't save the original order.--}--module Nub- ( hashNub- , ordNub- , sortNub- , unstableNub- ) where--import Data.Eq (Eq)-import Data.Hashable (Hashable)-import Data.HashSet as HashSet-import Data.Ord (Ord)-import qualified Data.Set as Set-import Prelude ((.))---- | Like 'Prelude.nub' but runs in @O(n * log n)@ time and requires 'Ord'.------ >>> ordNub [3, 3, 3, 2, 2, -1, 1]--- [3, 2, -1, 1]-ordNub :: (Ord a) => [a] -> [a]-ordNub = go Set.empty- where- go _ [] = []- go s (x:xs) =- if x `Set.member` s- then go s xs- else x : go (Set.insert x s) xs---- | Like 'Prelude.nub' but runs in @O(n * log_16(n))@ time and requires 'Hashable'.------ >>> hashNub [3, 3, 3, 2, 2, -1, 1]--- [3, 2, -1, 1]-hashNub :: (Eq a, Hashable a) => [a] -> [a]-hashNub = go HashSet.empty- where- go _ [] = []- go s (x:xs) =- if x `HashSet.member` s- then go s xs- else x : go (HashSet.insert x s) xs---- | Like 'ordNub' but also sorts a list.------ >>> sortNub [3, 3, 3, 2, 2, -1, 1]--- [-1, 1, 2, 3]-sortNub :: (Ord a) => [a] -> [a]-sortNub = Set.toList . Set.fromList---- | Like 'hashNub' but has better performance and also doesn't save the order.------ >>> unstableNub [3, 3, 3, 2, 2, -1, 1]--- [1, 2, 3, -1]-unstableNub :: (Eq a, Hashable a) => [a] -> [a]-unstableNub = HashSet.toList . HashSet.fromList
− src/Print.hs
@@ -1,68 +0,0 @@-{-# LANGUAGE ExplicitForAll #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE Trustworthy #-}---- | Generalization of 'Prelude.putStr' and 'Prelude.putStrLn' functions.--module Print- ( Print (..)- , print- , putText- , putLText- ) where--import Data.Function ((.))--import Monad.Trans (MonadIO, liftIO)--import qualified Base-import qualified Prelude (print, putStr, putStrLn)--import qualified Data.ByteString.Char8 as BS-import qualified Data.ByteString.Lazy.Char8 as BL--import qualified Data.Text as T-import qualified Data.Text.IO as T--import qualified Data.Text.Lazy as TL-import qualified Data.Text.Lazy.IO as TL---- | Polymorfic over string and lifted to 'MonadIO' printing functions.-class Print a where- putStr :: MonadIO m => a -> m ()- putStrLn :: MonadIO m => a -> m ()--instance Print T.Text where- putStr = liftIO . T.putStr- putStrLn = liftIO . T.putStrLn--instance Print TL.Text where- putStr = liftIO . TL.putStr- putStrLn = liftIO . TL.putStrLn--instance Print BS.ByteString where- putStr = liftIO . BS.putStr- putStrLn = liftIO . BS.putStrLn--instance Print BL.ByteString where- putStr = liftIO . BL.putStr- putStrLn = liftIO . BL.putStrLn--instance Print [Base.Char] where- putStr = liftIO . Prelude.putStr- putStrLn = liftIO . Prelude.putStrLn---- | Lifted version of 'Prelude.print'.-print :: forall a m . (MonadIO m, Base.Show a) => a -> m ()-print = liftIO . Prelude.print---- | Specialized to 'T.Text' version of 'putStrLn' or forcing type inference.-putText :: MonadIO m => T.Text -> m ()-putText = putStrLn-{-# SPECIALIZE putText :: T.Text -> Base.IO () #-}---- | Specialized to 'TL.Text' version of 'putStrLn' or forcing type inference.-putLText :: MonadIO m => TL.Text -> m ()-putLText = putStrLn-{-# SPECIALIZE putLText :: TL.Text -> Base.IO () #-}
− src/String.hs
@@ -1,196 +0,0 @@-{-# LANGUAGE ExplicitForAll #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeSynonymInstances #-}---- | Type classes for convertion between different string representations.--module String- ( module Data.String-- -- * Text- , module Text.Read- , module Data.Text- , module Data.Text.Lazy- , module Data.Text.Encoding- , module Data.Text.Encoding.Error-- , module Data.ByteString-- , ConvertUtf8 (..)- , ToString (..)- , ToLText (..)- , ToText (..)-- -- * Buildable class- , Buildable-- -- * Show and read functions- , readEither- , show- , pretty- , prettyL-- -- * Convenient type aliases- , LText- , LByteString- ) where----- for reexport-import Data.ByteString (ByteString)-import Data.String (IsString (..))-import Data.Text (Text, lines, unlines, unwords, words)-import Data.Text.Buildable (Buildable (build))-import Data.Text.Encoding (decodeUtf8', decodeUtf8With)-import Data.Text.Encoding.Error (OnDecodeError, OnError, UnicodeException, lenientDecode,- strictDecode)-import Data.Text.Lazy (fromStrict, toStrict)-import Text.Read (Read, readMaybe, reads)---- for internal usage-import Data.Bifunctor (first)-import Data.Either (Either)-import Data.Function (id, (.))-import Data.String (String)-import Data.Text.Lazy.Builder (toLazyText)--import Functor ((<$>))--import qualified Base as Base (Show (show))-import qualified Data.ByteString as B-import qualified Data.ByteString.Lazy as LB-import qualified Data.ByteString.Lazy.UTF8 as LBU-import qualified Data.ByteString.UTF8 as BU-import qualified Data.Text as T-import qualified Data.Text.Encoding as T-import qualified Data.Text.Encoding.Error as T-import qualified Data.Text.Lazy as LT-import qualified Data.Text.Lazy.Encoding as LT-import qualified Text.Read (readEither)---- | Type synonym for 'Data.Text.Lazy.Text'.-type LText = LT.Text---- | Type synonym for 'Data.ByteString.Lazy.ByteString'.-type LByteString = LB.ByteString----- | Type class for conversion to utf8 representation of text.-class ConvertUtf8 a b where- -- | Encode as utf8 string (usually 'B.ByteString').- --- -- >>> encodeUtf8 @Text @ByteString "патак"- -- "\208\191\208\176\209\130\208\176\208\186"- encodeUtf8 :: a -> b-- -- | Decode from utf8 string.- --- -- >>> decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186"- -- "\1087\1072\1090\1072\1082"- -- >>> putStrLn $ decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186"- -- патак- decodeUtf8 :: b -> a-- -- | Decode as utf8 string but returning execption if byte sequence is malformed.- --- -- >>> decodeUtf8 @Text @ByteString "\208\208\176\209\130\208\176\208\186"- -- "\65533\65533\1090\1072\1082"- -- >>> decodeUtf8Strict @Text @ByteString "\208\208\176\209\130\208\176\208\186"- -- Left Cannot decode byte '\xd0': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream- decodeUtf8Strict :: b -> Either T.UnicodeException a--instance ConvertUtf8 String B.ByteString where- encodeUtf8 = BU.fromString- decodeUtf8 = BU.toString- decodeUtf8Strict = (T.unpack <$>) . decodeUtf8Strict--instance ConvertUtf8 T.Text B.ByteString where- encodeUtf8 = T.encodeUtf8- decodeUtf8 = T.decodeUtf8With T.lenientDecode- decodeUtf8Strict = T.decodeUtf8'--instance ConvertUtf8 LT.Text B.ByteString where- encodeUtf8 = LB.toStrict . encodeUtf8- decodeUtf8 = LT.decodeUtf8With T.lenientDecode . LB.fromStrict- decodeUtf8Strict = decodeUtf8Strict . LB.fromStrict--instance ConvertUtf8 String LB.ByteString where- encodeUtf8 = LBU.fromString- decodeUtf8 = LBU.toString- decodeUtf8Strict = (T.unpack <$>) . decodeUtf8Strict--instance ConvertUtf8 T.Text LB.ByteString where- encodeUtf8 = LB.fromStrict . T.encodeUtf8- decodeUtf8 = T.decodeUtf8With T.lenientDecode . LB.toStrict- decodeUtf8Strict = T.decodeUtf8' . LB.toStrict--instance ConvertUtf8 LT.Text LB.ByteString where- encodeUtf8 = LT.encodeUtf8- decodeUtf8 = LT.decodeUtf8With T.lenientDecode- decodeUtf8Strict = LT.decodeUtf8'---- | Type class for converting other strings to 'T.Text'.-class ToText a where- toText :: a -> T.Text--instance ToText String where- toText = T.pack--instance ToText T.Text where- toText = id--instance ToText LT.Text where- toText = LT.toStrict---- | Type class for converting other strings to 'LT.Text'.-class ToLText a where- toLText :: a -> LT.Text--instance ToLText String where- toLText = LT.pack--instance ToLText T.Text where- toLText = LT.fromStrict--instance ToLText LT.Text where- toLText = id---- | Type class for converting other strings to 'String'.-class ToString a where- toString :: a -> String--instance ToString String where- toString = id--instance ToString T.Text where- toString = T.unpack--instance ToString LT.Text where- toString = LT.unpack---- | Polymorhpic version of 'Text.Read.readEither'.------ >>> readEither @Text @Int "123"--- Right 123--- >>> readEither @Text @Int "aa"--- Left "Prelude.read: no parse"-readEither :: (ToString a, Read b) => a -> Either Text b-readEither = first toText . Text.Read.readEither . toString---- | Generalized version of 'Prelude.show'.-show :: forall b a . (Base.Show a, IsString b) => a -> b-show x = fromString (Base.show x)-{-# SPECIALIZE show :: Base.Show a => a -> Text #-}-{-# SPECIALIZE show :: Base.Show a => a -> LText #-}-{-# SPECIALIZE show :: Base.Show a => a -> ByteString #-}-{-# SPECIALIZE show :: Base.Show a => a -> LByteString #-}-{-# SPECIALIZE show :: Base.Show a => a -> String #-}---- | Functions to show pretty output for buildable data types.-pretty :: Buildable a => a -> Text-pretty = toStrict . prettyL---- | Similar to 'pretty' but for 'LText'.-prettyL :: Buildable a => a -> LText-prettyL = toLazyText . build
− src/TypeOps.hs
@@ -1,59 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ExplicitNamespaces #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}--#if __GLASGOW_HASKELL__ <= 710-{-# LANGUAGE Trustworthy #-}-#else-{-# LANGUAGE Safe #-}-#endif---- | Type operators for writing convenient type signatures.--module TypeOps- ( type Each- , type With- , type ($)- ) where--#if __GLASGOW_HASKELL__ <= 710-import GHC.Prim (Constraint)-#else-import Data.Kind (Constraint)-#endif--import Control.Type.Operator (type ($), type (<+>))---- | Map several constraints over several variables.------ @--- f :: Each [Show, Read] [a, b] => a -> b -> String--- =--- f :: (Show a, Show b, Read a, Read b) => a -> b -> String--- @------ To specify list with single constraint / variable, don't forget to prefix--- it with @\'@:------ @--- f :: Each '[Show] [a, b] => a -> b -> String--- @-type family Each (c :: [k -> Constraint]) (as :: [k]) where- Each c '[] = (() :: Constraint)- Each c (h ': t) = (c <+> h, Each c t)---- | Map several constraints over a single variable.--- Note, that @With a b ≡ Each a '[b]@------ @--- a :: With [Show, Read] a => a -> a--- =--- a :: (Show a, Read a) => a -> a--- @-type With a b = a <+> b
src/Universum.hs view
@@ -1,168 +1,61 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE ExplicitForAll #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE Trustworthy #-} -- | Main module that reexports all functionality allowed to use -- without importing any other modules. Just add next lines to your -- module to replace default ugly 'Prelude' with better one. -- -- @--- {-# LANGUAGE NoImplicitPrelude #-}+-- {-\# LANGUAGE NoImplicitPrelude \#-} -- -- import Universum -- @ module Universum ( -- * Reexports from base and from modules in this repo- module X -- Should I expand this to all modules to remove haddock warnings?- , module Base+ module Universum.Applicative+ , module Universum.Base+ , module Universum.Bool+ , module Universum.Container+ , module Universum.Debug+ , module Universum.DeepSeq+ , module Universum.Exception+ , module Universum.Function+ , module Universum.Functor+ , module Universum.Lifted+ , module Universum.List+ , module Universum.Monad+ , module Universum.Monoid+ , module Universum.Nub+ , module Universum.Print+ , module Universum.String+ , module Universum.TypeOps+ , module Universum.VarArg - -- * Useful standard unclassifed functions- , evaluateNF- , evaluateNF_- , evaluateWHNF- , evaluateWHNF_- , identity- , map- , uncons- , unsnoc+ -- * Lenses+ , module Lens.Micro+ , module Lens.Micro.Mtl ) where -import Applicative as X-import Bool as X-import Container as X-import Debug as X-import Exceptions as X-import Functor as X-import Lifted as X-import List as X-import Monad as X-import Print as X-import String as X-import TypeOps as X-import VarArg as X--import Base as Base hiding (error, show, showFloat,- showList, showSigned, showSignedFloat,- showsPrec, undefined)---- Maybe'ized version of partial functions-import Safe as X (atDef, atMay, foldl1May, foldr1May,- headDef, headMay, initDef, initMay,- initSafe, lastDef, lastMay, tailDef,- tailMay, tailSafe)---- Applicatives and Bifunctors and Arrows-import Control.Applicative as X (Alternative (..), Applicative (..),- Const (..), ZipList (..), liftA, liftA2,- liftA3, optional, (<**>))-import Control.Arrow as X ((&&&))-import Data.Bifunctor as X (Bifunctor (..))---- Base typeclasses-import Data.Eq as X (Eq (..))-import Data.Foldable as X (Foldable, concat, concatMap, foldlM,- foldrM, maximumBy, minimumBy)-import Data.Functor.Identity as X (Identity (..))-import Data.Ord as X (Down (..), Ord (..), Ordering (..),- comparing)-import Data.Traversable as X (Traversable (..), fmapDefault,- foldMapDefault, forM, mapAccumL,- mapAccumR)--#if ( __GLASGOW_HASKELL__ >= 800 )-import Data.List.NonEmpty as X (NonEmpty (..), nonEmpty)-import Data.Monoid as X hiding ((<>))-import Data.Semigroup as X (Option (..), Semigroup (sconcat, stimes, (<>)),- WrappedMonoid, cycle1, mtimesDefault,- stimesIdempotent, stimesIdempotentMonoid,- stimesMonoid)-#else-import Data.Monoid as X hiding ((<>))-#endif---- Deepseq-import Control.DeepSeq as X (NFData (..), deepseq, force, ($!!))---- Data structures-import Data.Tuple as X (curry, fst, snd, swap, uncurry)--#if ( __GLASGOW_HASKELL__ >= 710 )-import Data.Proxy as X (Proxy (..))-import Data.Typeable as X (Typeable)-import Data.Void as X (Void, absurd, vacuous)-#endif---- Base types-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.Word as X (Word, Word16, Word32, Word64, Word8,- byteSwap16, byteSwap32, byteSwap64)--import Data.Function as X (const, fix, flip, on, ($), (.))---- Generics-import GHC.Generics as X (Generic)---- IO-import System.IO as X (FilePath, Handle, IOMode (..), stderr,- stdin, stdout, withFile)+import Universum.Applicative+import Universum.Base+import Universum.Bool+import Universum.Container+import Universum.Debug+import Universum.DeepSeq+import Universum.Exception+import Universum.Function+import Universum.Functor+import Universum.Lifted+import Universum.List+import Universum.Monad+import Universum.Monoid+import Universum.Nub+import Universum.Print+import Universum.String+import Universum.TypeOps+import Universum.VarArg -- Lenses-import Lens.Micro as X (Lens, Lens', Traversal, Traversal', over,- set, (%~), (&), (.~), (<&>), (^.), (^..),- (^?), _1, _2, _3, _4, _5)-import Lens.Micro.Mtl as X (preuse, preview, use, view)---- For internal usage only-import qualified Control.Exception.Base (evaluate)---- | Renamed version of 'Prelude.id'.-identity :: a -> a-identity x = x---- | 'Prelude.map' generalized to 'Functor'.-map :: Functor f => (a -> b) -> f a -> f b-map = fmap---- | Destructuring list into its head and tail if possible. This function is total.------ >>> uncons []--- Nothing--- >>> uncons [1..5]--- Just (1,[2,3,4,5])--- >>> uncons (5 : [1..5]) >>= \(f, l) -> pure $ f == length l--- Just True-uncons :: [a] -> Maybe (a, [a])-uncons [] = Nothing-uncons (x:xs) = Just (x, xs)---- | Similar to 'uncons' but destructuring list into its last element and--- everything before it.-unsnoc :: [x] -> Maybe ([x],x)-unsnoc = foldr go Nothing- where- go x mxs = Just (case mxs of- Nothing -> ([], x)- Just (xs, e) -> (x:xs, e))---- | Lifted alias for 'Control.Exception.Base.evaluate' with clearer name.-evaluateWHNF :: MonadIO m => a -> m a-evaluateWHNF = liftIO . Control.Exception.Base.evaluate---- | Like 'evaluateWNHF' but discards value.-evaluateWHNF_ :: MonadIO m => a -> m ()-evaluateWHNF_ what = (`seq` ()) <$!> evaluateWHNF what---- | Alias for @evaluateWHNF . force@ with clearer name.-evaluateNF :: (X.NFData a, MonadIO m) => a -> m a-evaluateNF = evaluateWHNF . force---- | Alias for @evaluateWHNF . rnf@. Similar to 'evaluateNF'--- but discards resulting value.-evaluateNF_ :: (X.NFData a, MonadIO m) => a -> m ()-evaluateNF_ = evaluateWHNF . rnf+import Lens.Micro (Lens, Lens', Traversal, Traversal', over, set, (%~), (&), (.~), (<&>), (^.),+ (^..), (^?), _1, _2, _3, _4, _5)+import Lens.Micro.Mtl (preuse, preview, use, view)
+ src/Universum/Applicative.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE Safe #-}++-- | Convenient utils to work with 'Applicative'. There were more functions in this module+-- (see <https://www.stackage.org/haddock/lts-8.9/protolude-0.1.10/Applicative.html protolude version>)+-- but only convenient ans most used are left.++module Universum.Applicative+ ( module Control.Applicative+ , pass+ ) where++import Control.Applicative (Alternative (..), Applicative (..), Const (..), ZipList (..), liftA2,+ liftA3, optional, (<**>))++-- | Shorter alias for @pure ()@.+--+-- >>> pass :: Maybe ()+-- Just ()+pass :: Applicative f => f ()+pass = pure ()++{-+orAlt :: (Alternative f, Monoid a) => f a -> f a+orAlt f = f <|> pure mempty++orEmpty :: Alternative f => Bool -> a -> f a+orEmpty b a = if b then pure a else empty++eitherA :: Alternative f => f a -> f b -> f (Either a b)+eitherA a b = (Left <$> a) <|> (Right <$> b)++purer :: (Applicative f, Applicative g) => a -> f (g a)+purer = pure . pure++liftAA2 :: (Applicative f, Applicative g) => (a -> b -> c) -> f (g a) -> f (g b) -> f (g c)+liftAA2 = liftA2 . liftA2++(<<*>>) :: (Applicative f, Applicative g) => f (g (a -> b)) -> f (g a) -> f (g b)+(<<*>>) = liftA2 (<*>)+-}
+ src/Universum/Base.hs view
@@ -0,0 +1,127 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE Unsafe #-}++-- | Reexports from @GHC.*@ modules of <https://www.stackage.org/lts-8.9/package/base-4.9.1.0 base>+-- package.++module Universum.Base+ ( -- * Base types+ module Data.Bits+ , module Data.Char+ , module Data.Int+ , module Data.Word++ -- * Base type classes+ , module Data.Eq+ , module Data.Foldable+ , module Data.Ord+ , module Data.Traversable++ -- * System IO+ , module System.IO++ -- * Base GHC types+#if ( __GLASGOW_HASKELL__ >= 710 )+ , module Data.Proxy+ , module Data.Typeable+ , module Data.Void+#endif+ , module GHC.Base+ , module GHC.Enum+ , module GHC.Exts+ , module GHC.Float+ , module GHC.Generics+ , module GHC.Num+ , module GHC.Real+ , module GHC.Show++#if MIN_VERSION_base(4,10,0)+ , module GHC.TypeNats+#else+ , module GHC.TypeLits+#endif+ , module GHC.Types++#if ( __GLASGOW_HASKELL__ >= 800 )+ , module GHC.OverloadedLabels+ , module GHC.ExecutionStack+ , module GHC.Stack+#endif++ , ($!)+ ) where++-- Base types+import Data.Bits (xor)+import Data.Char (chr)+import Data.Int (Int, Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8, byteSwap16, byteSwap32, byteSwap64)++-- IO+import System.IO (FilePath, Handle, IOMode (..), stderr, stdin, stdout, withFile)++-- Base typeclasses+import Data.Eq (Eq (..))+import Data.Foldable (Foldable, concat, concatMap, foldlM, foldrM, maximumBy, minimumBy)+import Data.Ord (Down (..), Ord (..), Ordering (..), comparing)+import Data.Traversable (Traversable (..), fmapDefault, foldMapDefault, forM, mapAccumL, mapAccumR)++-- Base GHC types+#if ( __GLASGOW_HASKELL__ >= 710 )+import Data.Proxy (Proxy (..))+import Data.Typeable (Typeable)+import Data.Void (Void, absurd, vacuous)+#endif++import GHC.Base (String, asTypeOf, maxInt, minInt, ord, seq, (++))+import GHC.Enum (Bounded (..), Enum (..), boundedEnumFrom, boundedEnumFromThen)+import GHC.Exts (Constraint, FunPtr, Ptr)+import GHC.Float (Double (..), Float (..), Floating (..))+import GHC.Generics (Generic)+import GHC.Num (Integer, Num (..), subtract)+import GHC.Real hiding (showSigned, (%))+import GHC.Show (Show)+#if MIN_VERSION_base(4,10,0)+import GHC.TypeNats (CmpNat, KnownNat, Nat, SomeNat (..), natVal, someNatVal)+#else+import GHC.TypeLits (CmpNat, KnownNat, Nat, SomeNat (..), natVal, someNatVal)+#endif++import GHC.Types (Bool, Char, Coercible, IO, Int, Ordering, Word)+++#if ( __GLASGOW_HASKELL__ >= 800 )+import GHC.ExecutionStack (getStackTrace, showStackTrace)+import GHC.OverloadedLabels (IsLabel (..))+import GHC.Stack (CallStack, HasCallStack, callStack, currentCallStack, getCallStack,+ prettyCallStack, prettySrcLoc, withFrozenCallStack)+#endif++-- Pending GHC 8.2 we'll expose these.++{-+import GHC.Records as X (+ HasField(..)+ )++<<<<<<< HEAD+=======+import Data.Kind as X (+ type (*)+ , type Type+ )+-}+++-- | Stricter version of 'Data.Function.$' operator.+-- Default Prelude defines this at the toplevel module, so we do as well.+--+-- >>> const 3 $ undefined+-- 3+-- >>> const 3 $! undefined+-- CallStack (from HasCallStack):+-- error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err+($!) :: (a -> b) -> a -> b+f $! x = let !vx = x in f vx+infixr 0 $!
+ src/Universum/Bool.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE Safe #-}++-- | Convenient commonly used and very helpful functions to work with+-- 'Bool' and also with monads.++module Universum.Bool+ ( module Universum.Bool.Guard+ , module Universum.Bool.Reexport+ ) where++import Universum.Bool.Guard+import Universum.Bool.Reexport
+ src/Universum/Bool/Guard.hs view
@@ -0,0 +1,57 @@+module Universum.Bool.Guard+ ( guardM+ , ifM+ , unlessM+ , whenM+ ) where++import Universum.Bool.Reexport (Bool, guard, unless, when)+import Universum.Function (flip)+import Universum.Monad (Monad, MonadPlus, (>>=))++-- | Monadic version of 'when'.+--+-- >>> whenM (pure False) $ putText "No text :("+-- >>> whenM (pure True) $ putText "Yes text :)"+-- Yes text :)+-- >>> whenM (Just True) (pure ())+-- Just ()+-- >>> whenM (Just False) (pure ())+-- Just ()+-- >>> whenM Nothing (pure ())+-- Nothing+whenM :: Monad m => m Bool -> m () -> m ()+whenM p m = p >>= flip when m+{-# INLINE whenM #-}++-- | Monadic version of 'unless'.+--+-- >>> unlessM (pure False) $ putText "No text :("+-- No text :(+-- >>> unlessM (pure True) $ putText "Yes text :)"+unlessM :: Monad m => m Bool -> m () -> m ()+unlessM p m = p >>= flip unless m+{-# INLINE unlessM #-}++-- | Monadic version of @if-then-else@.+--+-- >>> ifM (pure True) (putText "True text") (putText "False text")+-- 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 = f >>= guard+{-# INLINE guardM #-}
+ src/Universum/Bool/Reexport.hs view
@@ -0,0 +1,7 @@+module Universum.Bool.Reexport+ ( module Control.Monad+ , module Data.Bool+ ) where++import Control.Monad (guard, unless, when)+import Data.Bool (Bool (..), bool, not, otherwise, (&&), (||))
+ src/Universum/Container.hs view
@@ -0,0 +1,9 @@+-- | This module exports all container-related stuff.++module Universum.Container+ ( module Universum.Container.Class+ , module Universum.Container.Reexport+ ) where++import Universum.Container.Class+import Universum.Container.Reexport
+ src/Universum/Container/Class.hs view
@@ -0,0 +1,775 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ConstrainedClassMethods #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}++-- | Reimagined approach for 'Foldable' type hierarchy. Forbids usages+-- of 'length' function and similar over 'Maybe' and other potentially unsafe+-- data types. It was proposed to use @-XTypeApplication@ for such cases.+-- But this approach is not robust enough because programmers are human and can+-- easily forget to do this. For discussion see this topic:+-- <https://www.reddit.com/r/haskell/comments/60r9hu/proposal_suggest_explicit_type_application_for/ Suggest explicit type application for Foldable length and friends>++module Universum.Container.Class+ ( -- * Foldable-like classes and methods+ ToList (..)+ , Container (..)++ , sum+ , product++ , mapM_+ , forM_+ , traverse_+ , for_+ , sequenceA_+ , sequence_+ , asum++ -- * Others+ , One(..)+ ) where++import Data.Coerce (Coercible, coerce)+import Prelude hiding (all, and, any, elem, foldMap, foldl, foldr, mapM_, notElem, or, product,+ sequence_, sum)++import Universum.Applicative (Alternative (..), Const, ZipList, pass)+import Universum.Base (Constraint, Word8)+import Universum.Container.Reexport (HashMap, HashSet, Hashable, IntMap, IntSet, Map, Seq, Set,+ Vector)+import Universum.Functor (Identity)+import Universum.Monad.Reexport (fromMaybe)+import Universum.Monoid (All (..), Any (..), Dual, First (..), Last, Product, Sum)++#if __GLASGOW_HASKELL__ >= 800+import GHC.Err (errorWithoutStackTrace)+import GHC.TypeLits (ErrorMessage (..), Symbol, TypeError)+#endif++#if ( __GLASGOW_HASKELL__ >= 800 )+import qualified Data.List.NonEmpty as NE+import Universum.Monoid (NonEmpty)+#endif++import qualified Data.Foldable as Foldable++import qualified Data.List as List (null)++import qualified Data.Sequence as SEQ++import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BSL++import qualified Data.Text as T+import qualified Data.Text.Lazy as TL++import qualified Data.HashMap.Strict as HM+import qualified Data.HashSet as HashSet+import qualified Data.IntMap as IM+import qualified Data.IntSet as IS+import qualified Data.Map as M+import qualified Data.Set as Set++import qualified Data.Vector as V+import qualified Data.Vector.Primitive as VP+import qualified Data.Vector.Storable as VS+import qualified Data.Vector.Unboxed as VU++----------------------------------------------------------------------------+-- Containers (e.g. tuples aren't containers)+----------------------------------------------------------------------------++-- | Default implementation of 'Element' associated type family.+type family ElementDefault (t :: *) :: * where+ ElementDefault (f a) = a++-- | Type class for data types that can be converted to List.+-- Fully compatible with 'Foldable'.+-- Contains very small and safe subset of 'Foldable' functions.+--+-- You can define 'Tolist' by just defining 'toList' function.+-- But the following law should be met:+--+-- @'null' ≡ 'List.null' . 'toList'@+--+class ToList t where+ -- | Type of element for some container. Implemented as an asscociated type family because+ -- some containers are monomorphic over element type (like 'T.Text', 'IntSet', etc.)+ -- so we can't implement nice interface using old higher-kinded types+ -- approach. Implementing this as an associated type family instead of+ -- top-level family gives you more control over element types.+ type Element t :: *+ type Element t = ElementDefault t++ -- | Convert container to list of elements.+ --+ -- >>> toList (Just True)+ -- [True]+ -- >>> toList @Text "aba"+ -- "aba"+ -- >>> :t toList @Text "aba"+ -- toList @Text "aba" :: [Char]+ toList :: t -> [Element t]+ default toList :: (Foldable f, t ~ f a, Element t ~ a) => t -> [Element t]+ toList = Foldable.toList+ {-# INLINE toList #-}++ -- | Checks whether container is empty.+ --+ -- >>> null @Text ""+ -- True+ -- >>> null @Text "aba"+ -- False+ null :: t -> Bool+ null = List.null . toList+ {-# INLINE null #-}++----------------------------------------------------------------------------+-- Instances for monomorphic containers+----------------------------------------------------------------------------++instance ToList T.Text where+ type Element T.Text = Char+ toList = T.unpack+ {-# INLINE toList #-}+ null = T.null+ {-# INLINE null #-}++instance ToList TL.Text where+ type Element TL.Text = Char+ toList = TL.unpack+ {-# INLINE toList #-}+ null = TL.null+ {-# INLINE null #-}++instance ToList BS.ByteString where+ type Element BS.ByteString = Word8+ toList = BS.unpack+ {-# INLINE toList #-}+ null = BS.null+ {-# INLINE null #-}++instance ToList BSL.ByteString where+ type Element BSL.ByteString = Word8+ toList = BSL.unpack+ {-# INLINE toList #-}+ null = BSL.null+ {-# INLINE null #-}++instance ToList IntSet where+ type Element IntSet = Int+ toList = IS.toList+ {-# INLINE toList #-}+ null = IS.null+ {-# INLINE null #-}++----------------------------------------------------------------------------+-- Boilerplate instances (duplicate Foldable)+----------------------------------------------------------------------------++-- Basic types+instance ToList [a]+instance ToList (Maybe a)+instance ToList (Either a b)+instance ToList (Identity a)+instance ToList (Const a b)++#if __GLASGOW_HASKELL__ >= 800+-- Algebraic types+instance ToList (Dual a)+instance ToList (First a)+instance ToList (Last a)+instance ToList (Product a)+instance ToList (Sum a)+instance ToList (NonEmpty a)+instance ToList (ZipList a)+#endif++-- Containers+instance ToList (HashMap k v)+instance ToList (HashSet v)+instance ToList (IntMap v)+instance ToList (Map k v)+instance ToList (Set v)+instance ToList (Seq a)+instance ToList (Vector a)++----------------------------------------------------------------------------+-- Additional operations that don't make much sense for e.g. Maybe+----------------------------------------------------------------------------++-- | A class for 'ToList's that aren't trivial like 'Maybe' (e.g. can hold+-- more than one value)+class ToList t => Container t where+ -- | Constraint for elements. This can be used to implement more efficient+ -- implementation of some methods.+ type ElementConstraint t :: * -> Constraint+ type ElementConstraint t = Eq++ foldr :: (Element t -> b -> b) -> b -> t -> b+ default foldr :: (Foldable f, t ~ f a, Element t ~ a) => (Element t -> b -> b) -> b -> t -> b+ foldr = Foldable.foldr+ {-# INLINE foldr #-}++ foldl :: (b -> Element t -> b) -> b -> t -> b+ default foldl :: (Foldable f, t ~ f a, Element t ~ a) => (b -> Element t -> b) -> b -> t -> b+ foldl = Foldable.foldl+ {-# INLINE foldl #-}++ foldl' :: (b -> Element t -> b) -> b -> t -> b+ default foldl' :: (Foldable f, t ~ f a, Element t ~ a) => (b -> Element t -> b) -> b -> t -> b+ foldl' = Foldable.foldl'+ {-# INLINE foldl' #-}++ length :: t -> Int+ default length :: (Foldable f, t ~ f a, Element t ~ a) => t -> Int+ length = Foldable.length+ {-# INLINE length #-}++ elem :: ElementConstraint t (Element t) => Element t -> t -> Bool+ default elem :: ( Foldable f+ , t ~ f a+ , Element t ~ a+ , ElementConstraint t ~ Eq+ , ElementConstraint t (Element t)+ ) => Element t -> t -> Bool+ elem = Foldable.elem+ {-# INLINE elem #-}++ maximum :: Ord (Element t) => t -> Element t+ default maximum :: (Foldable f, t ~ f a, Element t ~ a, Ord (Element t)) => t -> Element t+ maximum = Foldable.maximum+ {-# INLINE maximum #-}++ minimum :: Ord (Element t) => t -> Element t+ default minimum :: (Foldable f, t ~ f a, Element t ~ a, Ord (Element t)) => t -> Element t+ minimum = Foldable.minimum+ {-# INLINE minimum #-}++ foldMap :: Monoid m => (Element t -> m) -> t -> m+ foldMap f = foldr (mappend . f) mempty+ {-# INLINE foldMap #-}++ fold :: Monoid (Element t) => t -> Element t+ fold = foldMap id+ {-# INLINE fold #-}++ foldr' :: (Element t -> b -> b) -> b -> t -> b+ foldr' f z0 xs = foldl f' id xs z0+ where f' k x z = k $! f x z+ {-# INLINE foldr' #-}++ foldr1 :: (Element t -> Element t -> Element t) -> t -> Element t+ foldr1 f xs =+#if __GLASGOW_HASKELL__ >= 800+ fromMaybe (errorWithoutStackTrace "foldr1: empty structure")+ (foldr mf Nothing xs)+#else+ fromMaybe (error "foldr1: empty structure")+ (foldr mf Nothing xs)+#endif+ where+ mf x m = Just (case m of+ Nothing -> x+ Just y -> f x y)+ {-# INLINE foldr1 #-}++ foldl1 :: (Element t -> Element t -> Element t) -> t -> Element t+ foldl1 f xs =+#if __GLASGOW_HASKELL__ >= 800+ fromMaybe (errorWithoutStackTrace "foldl1: empty structure")+ (foldl mf Nothing xs)+#else+ fromMaybe (error "foldl1: empty structure")+ (foldl mf Nothing xs)+#endif+ where+ mf m y = Just (case m of+ Nothing -> y+ Just x -> f x y)+ {-# INLINE foldl1 #-}++ notElem :: ElementConstraint t (Element t) => Element t -> t -> Bool+ notElem x = not . elem x+ {-# INLINE notElem #-}++ all :: (Element t -> Bool) -> t -> Bool+ all p = getAll #. foldMap (All #. p)+ any :: (Element t -> Bool) -> t -> Bool+ any p = getAny #. foldMap (Any #. p)+ {-# INLINE all #-}+ {-# INLINE any #-}++ and :: (Element t ~ Bool) => t -> Bool+ and = getAll #. foldMap All+ or :: (Element t ~ Bool) => t -> Bool+ or = getAny #. foldMap Any+ {-# INLINE and #-}+ {-# INLINE or #-}++ find :: (Element t -> Bool) -> t -> Maybe (Element t)+ find p = getFirst . foldMap (\ x -> First (if p x then Just x else Nothing))+ {-# INLINE find #-}++ safeHead :: t -> Maybe (Element t)+ safeHead = foldr (\x _ -> Just x) Nothing+ {-# INLINE safeHead #-}++----------------------------------------------------------------------------+-- Instances for monomorphic containers+----------------------------------------------------------------------------++instance Container T.Text where+ foldr = T.foldr+ {-# INLINE foldr #-}+ foldl = T.foldl+ {-# INLINE foldl #-}+ foldl' = T.foldl'+ {-# INLINE foldl' #-}+ foldr1 = T.foldr1+ {-# INLINE foldr1 #-}+ foldl1 = T.foldl1+ {-# INLINE foldl1 #-}+ length = T.length+ {-# INLINE length #-}+ elem c = T.isInfixOf (T.singleton c) -- there are rewrite rules for this+ {-# INLINE elem #-}+ maximum = T.maximum+ {-# INLINE maximum #-}+ minimum = T.minimum+ {-# INLINE minimum #-}+ all = T.all+ {-# INLINE all #-}+ any = T.any+ {-# INLINE any #-}+ find = T.find+ {-# INLINE find #-}+ safeHead = fmap fst . T.uncons+ {-# INLINE safeHead #-}++instance Container TL.Text where+ foldr = TL.foldr+ {-# INLINE foldr #-}+ foldl = TL.foldl+ {-# INLINE foldl #-}+ foldl' = TL.foldl'+ {-# INLINE foldl' #-}+ foldr1 = TL.foldr1+ {-# INLINE foldr1 #-}+ foldl1 = TL.foldl1+ {-# INLINE foldl1 #-}+ length = fromIntegral . TL.length+ {-# INLINE length #-}+ -- will be okay thanks to rewrite rules+ elem c s = TL.isInfixOf (TL.singleton c) s+ {-# INLINE elem #-}+ maximum = TL.maximum+ {-# INLINE maximum #-}+ minimum = TL.minimum+ {-# INLINE minimum #-}+ all = TL.all+ {-# INLINE all #-}+ any = TL.any+ {-# INLINE any #-}+ find = TL.find+ {-# INLINE find #-}+ safeHead = fmap fst . TL.uncons+ {-# INLINE safeHead #-}++instance Container BS.ByteString where+ foldr = BS.foldr+ {-# INLINE foldr #-}+ foldl = BS.foldl+ {-# INLINE foldl #-}+ foldl' = BS.foldl'+ {-# INLINE foldl' #-}+ foldr1 = BS.foldr1+ {-# INLINE foldr1 #-}+ foldl1 = BS.foldl1+ {-# INLINE foldl1 #-}+ length = BS.length+ {-# INLINE length #-}+ elem = BS.elem+ {-# INLINE elem #-}+ notElem = BS.notElem+ {-# INLINE notElem #-}+ maximum = BS.maximum+ {-# INLINE maximum #-}+ minimum = BS.minimum+ {-# INLINE minimum #-}+ all = BS.all+ {-# INLINE all #-}+ any = BS.any+ {-# INLINE any #-}+ find = BS.find+ {-# INLINE find #-}+ safeHead = fmap fst . BS.uncons+ {-# INLINE safeHead #-}++instance Container BSL.ByteString where+ foldr = BSL.foldr+ {-# INLINE foldr #-}+ foldl = BSL.foldl+ {-# INLINE foldl #-}+ foldl' = BSL.foldl'+ {-# INLINE foldl' #-}+ foldr1 = BSL.foldr1+ {-# INLINE foldr1 #-}+ foldl1 = BSL.foldl1+ {-# INLINE foldl1 #-}+ length = fromIntegral . BSL.length+ {-# INLINE length #-}+ elem = BSL.elem+ {-# INLINE elem #-}+ notElem = BSL.notElem+ {-# INLINE notElem #-}+ maximum = BSL.maximum+ {-# INLINE maximum #-}+ minimum = BSL.minimum+ {-# INLINE minimum #-}+ all = BSL.all+ {-# INLINE all #-}+ any = BSL.any+ {-# INLINE any #-}+ find = BSL.find+ {-# INLINE find #-}+ safeHead = fmap fst . BSL.uncons+ {-# INLINE safeHead #-}++instance Container IntSet where+ foldr = IS.foldr+ {-# INLINE foldr #-}+ foldl = IS.foldl+ {-# INLINE foldl #-}+ foldl' = IS.foldl'+ {-# INLINE foldl' #-}+ length = IS.size+ {-# INLINE length #-}+ elem = IS.member+ {-# INLINE elem #-}+ maximum = IS.findMax+ {-# INLINE maximum #-}+ minimum = IS.findMin+ {-# INLINE minimum #-}+ safeHead = fmap fst . IS.minView+ {-# INLINE safeHead #-}++----------------------------------------------------------------------------+-- Efficient instances+----------------------------------------------------------------------------++instance Container (Set v) where+ type ElementConstraint (Set v) = Ord+ elem = Set.member+ {-# INLINE elem #-}+ notElem = Set.notMember+ {-# INLINE notElem #-}++class (Eq a, Hashable a) => CanHash a+instance (Eq a, Hashable a) => CanHash a++instance Container (HashSet v) where+ type ElementConstraint (HashSet v) = CanHash+ elem = HashSet.member+ {-# INLINE elem #-}++----------------------------------------------------------------------------+-- Boilerplate instances (duplicate Foldable)+----------------------------------------------------------------------------++-- Basic types+instance Container [a]+instance Container (Const a b)++#if __GLASGOW_HASKELL__ >= 800+-- Algebraic types+instance Container (Dual a)+instance Container (First a)+instance Container (Last a)+instance Container (Product a)+instance Container (Sum a)+instance Container (NonEmpty a)+instance Container (ZipList a)+#endif++-- Containers+instance Container (HashMap k v)+instance Container (IntMap v)+instance Container (Map k v)+instance Container (Seq a)+instance Container (Vector a)++----------------------------------------------------------------------------+-- Derivative functions+----------------------------------------------------------------------------++-- | Stricter version of 'Prelude.sum'.+--+-- >>> sum [1..10]+-- 55+-- >>> sum (Just 3)+-- <interactive>:43:1: error:+-- • Do not use 'Foldable' methods on Maybe+-- • In the expression: sum (Just 3)+-- In an equation for ‘it’: it = sum (Just 3)+sum :: (Container t, Num (Element t)) => t -> Element t+sum = foldl' (+) 0++-- | Stricter version of 'Prelude.product'.+--+-- >>> product [1..10]+-- 3628800+-- >>> product (Right 3)+-- <interactive>:45:1: error:+-- • Do not use 'Foldable' methods on Either+-- • In the expression: product (Right 3)+-- In an equation for ‘it’: it = product (Right 3)+product :: (Container t, Num (Element t)) => t -> Element t+product = foldl' (*) 1++-- | Constrained to 'Container' version of 'Data.Foldable.traverse_'.+traverse_+ :: (Container t, Applicative f)+ => (Element t -> f b) -> t -> f ()+traverse_ f = foldr ((*>) . f) pass++-- | Constrained to 'Container' version of 'Data.Foldable.for_'.+for_+ :: (Container t, Applicative f)+ => t -> (Element t -> f b) -> f ()+for_ = flip traverse_+{-# INLINE for_ #-}++-- | Constrained to 'Container' version of 'Data.Foldable.mapM_'.+mapM_+ :: (Container t, Monad m)+ => (Element t -> m b) -> t -> m ()+mapM_ f= foldr ((>>) . f) pass++-- | Constrained to 'Container' version of 'Data.Foldable.forM_'.+forM_+ :: (Container t, Monad m)+ => t -> (Element t -> m b) -> m ()+forM_ = flip mapM_+{-# INLINE forM_ #-}++-- | Constrained to 'Container' version of 'Data.Foldable.sequenceA_'.+sequenceA_+ :: (Container t, Applicative f, Element t ~ f a)+ => t -> f ()+sequenceA_ = foldr (*>) pass++-- | Constrained to 'Container' version of 'Data.Foldable.sequence_'.+sequence_+ :: (Container t, Monad m, Element t ~ m a)+ => t -> m ()+sequence_ = foldr (>>) pass++-- | Constrained to 'Container' version of 'Data.Foldable.asum'.+asum+ :: (Container t, Alternative f, Element t ~ f a)+ => t -> f a+asum = foldr (<|>) empty+{-# INLINE asum #-}++----------------------------------------------------------------------------+-- Disallowed instances+----------------------------------------------------------------------------++#if __GLASGOW_HASKELL__ >= 800+type family DisallowInstance (z :: Symbol) :: ErrorMessage where+ DisallowInstance z = Text "Do not use 'Foldable' methods on " :<>: Text z+ :$$: Text "Suggestions:"+ :$$: Text " Instead of"+ :$$: Text " for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()"+ :$$: Text " use"+ :$$: Text " whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()"+ :$$: Text " whenRight :: Applicative f => Either l r -> (r -> f ()) -> f ()"+ :$$: Text ""+ :$$: Text " Instead of"+ :$$: Text " fold :: (Foldable t, Monoid m) => t m -> m"+ :$$: Text " use"+ :$$: Text " maybeToMonoid :: Monoid m => Maybe m -> m"+ :$$: Text ""+#endif++#define DISALLOW_TO_LIST_8(t, z) \+ instance TypeError (DisallowInstance z) => \+ ToList (t) where { \+ toList = undefined; \+ null = undefined; } \++#define DISALLOW_CONTAINER_8(t, z) \+ instance TypeError (DisallowInstance z) => \+ Container (t) where { \+ foldr = undefined; \+ foldl = undefined; \+ foldl' = undefined; \+ length = undefined; \+ elem = undefined; \+ maximum = undefined; \+ minimum = undefined; } \++#define DISALLOW_TO_LIST_7(t) \+ instance ForbiddenFoldable (t) => ToList (t) where { \+ toList = undefined; \+ null = undefined; } \++#define DISALLOW_CONTAINER_7(t) \+ instance ForbiddenFoldable (t) => Container (t) where { \+ foldr = undefined; \+ foldl = undefined; \+ foldl' = undefined; \+ length = undefined; \+ elem = undefined; \+ maximum = undefined; \+ minimum = undefined; } \++#if __GLASGOW_HASKELL__ >= 800+DISALLOW_TO_LIST_8((a, b),"tuples")+DISALLOW_CONTAINER_8((a, b),"tuples")+DISALLOW_CONTAINER_8(Maybe a,"Maybe")+DISALLOW_CONTAINER_8(Identity a,"Identity")+DISALLOW_CONTAINER_8(Either a b,"Either")+#else+class ForbiddenFoldable a+DISALLOW_TO_LIST_7((a, b))+DISALLOW_CONTAINER_7((a, b))+DISALLOW_CONTAINER_7(Maybe a)+DISALLOW_CONTAINER_7(Identity a)+DISALLOW_CONTAINER_7(Either a b)+#endif++----------------------------------------------------------------------------+-- One+----------------------------------------------------------------------------++-- | Type class for types that can be created from one element. @singleton@+-- is lone name for this function. Also constructions of different type differ:+-- @:[]@ for lists, two arguments for Maps. Also some data types are monomorphic.+--+-- >>> one True :: [Bool]+-- [True]+-- >>> one 'a' :: Text+-- "a"+-- >>> one (3, "hello") :: HashMap Int String+-- fromList [(3,"hello")]+class One x where+ type OneItem x+ -- | Create a list, map, 'Text', etc from a single element.+ one :: OneItem x -> x++-- Lists++instance One [a] where+ type OneItem [a] = a+ one = (:[])+ {-# INLINE one #-}++#if ( __GLASGOW_HASKELL__ >= 800 )+instance One (NE.NonEmpty a) where+ type OneItem (NE.NonEmpty a) = a+ one = (NE.:|[])+ {-# INLINE one #-}+#endif++instance One (SEQ.Seq a) where+ type OneItem (SEQ.Seq a) = a+ one = (SEQ.empty SEQ.|>)+ {-# INLINE one #-}++-- Monomorphic sequences++instance One T.Text where+ type OneItem T.Text = Char+ one = T.singleton+ {-# INLINE one #-}++instance One TL.Text where+ type OneItem TL.Text = Char+ one = TL.singleton+ {-# INLINE one #-}++instance One BS.ByteString where+ type OneItem BS.ByteString = Word8+ one = BS.singleton+ {-# INLINE one #-}++instance One BSL.ByteString where+ type OneItem BSL.ByteString = Word8+ one = BSL.singleton+ {-# INLINE one #-}++-- Maps++instance One (M.Map k v) where+ type OneItem (M.Map k v) = (k, v)+ one = uncurry M.singleton+ {-# INLINE one #-}++instance Hashable k => One (HM.HashMap k v) where+ type OneItem (HM.HashMap k v) = (k, v)+ one = uncurry HM.singleton+ {-# INLINE one #-}++instance One (IM.IntMap v) where+ type OneItem (IM.IntMap v) = (Int, v)+ one = uncurry IM.singleton+ {-# INLINE one #-}++-- Sets++instance One (Set v) where+ type OneItem (Set v) = v+ one = Set.singleton+ {-# INLINE one #-}++instance Hashable v => One (HashSet v) where+ type OneItem (HashSet v) = v+ one = HashSet.singleton+ {-# INLINE one #-}++instance One IntSet where+ type OneItem IntSet = Int+ one = IS.singleton+ {-# INLINE one #-}++-- Vectors++instance One (Vector a) where+ type OneItem (Vector a) = a+ one = V.singleton+ {-# INLINE one #-}++instance VU.Unbox a => One (VU.Vector a) where+ type OneItem (VU.Vector a) = a+ one = VU.singleton+ {-# INLINE one #-}++instance VP.Prim a => One (VP.Vector a) where+ type OneItem (VP.Vector a) = a+ one = VP.singleton+ {-# INLINE one #-}++instance VS.Storable a => One (VS.Vector a) where+ type OneItem (VS.Vector a) = a+ one = VS.singleton+ {-# INLINE one #-}++----------------------------------------------------------------------------+-- Utils+----------------------------------------------------------------------------++(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)+(#.) _f = coerce+{-# INLINE (#.) #-}
+ src/Universum/Container/Reexport.hs view
@@ -0,0 +1,25 @@+-- | This module reexports all container related stuff from 'Prelude'.++module Universum.Container.Reexport+ ( module Data.Hashable+ , module Data.HashMap.Strict+ , module Data.HashSet+ , module Data.IntMap.Strict+ , module Data.IntSet+ , module Data.Map.Strict+ , module Data.Sequence+ , module Data.Set+ , module Data.Tuple+ , module Data.Vector+ ) where++import Data.Hashable (Hashable)+import Data.HashMap.Strict (HashMap)+import Data.HashSet (HashSet)+import Data.IntMap.Strict (IntMap)+import Data.IntSet (IntSet)+import Data.Map.Strict (Map)+import Data.Sequence (Seq)+import Data.Set (Set)+import Data.Tuple (curry, fst, snd, swap, uncurry)+import Data.Vector (Vector)
+ src/Universum/Debug.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE Trustworthy #-}++-- | Functions for debugging. If you left these functions in your code+-- then warning is generated to remind you about left usages. Also some+-- functions (and data types) are convenient for prototyping.++module Universum.Debug+ ( Undefined (..)+ , error+ , trace+ , traceM+ , traceId+ , traceShow+ , traceShowId+ , traceShowM+ , undefined+ ) where++import Control.Monad (Monad, return)+import Data.Data (Data)+import Data.Text (Text, unpack)+import Data.Typeable (Typeable)+import GHC.Generics (Generic)+import System.IO.Unsafe (unsafePerformIO)++#if ( __GLASGOW_HASKELL__ >= 800 )+import GHC.Exts (RuntimeRep, TYPE)++import Universum.Base (HasCallStack)+#endif++import Universum.Applicative (pass)+import Universum.Print (Print, putStrLn)++import qualified Prelude as P++-- | Generalized over string version of 'Debug.Trace.trace' that leaves warnings.+{-# WARNING trace "'trace' remains in code" #-}+trace :: Print b => b -> a -> a+trace string expr = unsafePerformIO (do+ putStrLn string+ return expr)++-- | 'P.error' that takes 'Text' as an argument.+#if ( __GLASGOW_HASKELL__ >= 800 )+error :: forall (r :: RuntimeRep) . forall (a :: TYPE r) . HasCallStack+ => Text -> a+#else+error :: Text -> a+#endif+error s = P.error (unpack s)++-- | Version of 'Debug.Trace.traceShow' that leaves warning.+{-# WARNING traceShow "'traceShow' remains in code" #-}+traceShow :: P.Show a => a -> b -> b+traceShow a b = trace (P.show a) b++-- | Version of 'Debug.Trace.traceShow' that leaves warning.+{-# WARNING traceShowId "'traceShowId' remains in code" #-}+traceShowId :: P.Show a => a -> a+traceShowId a = trace (P.show a) a++-- | Version of 'Debug.Trace.traceShowM' that leaves warning.+{-# WARNING traceShowM "'traceShowM' remains in code" #-}+traceShowM :: (P.Show a, Monad m) => a -> m ()+traceShowM a = trace (P.show a) pass++-- | Version of 'Debug.Trace.traceM' that leaves warning and takes 'Text'.+{-# WARNING traceM "'traceM' remains in code" #-}+traceM :: (Monad m) => Text -> m ()+traceM s = trace (unpack s) pass++-- | Version of 'Debug.Trace.traceId' that leaves warning and takes 'Text'.+{-# WARNING traceId "'traceId' remains in code" #-}+traceId :: Text -> Text+traceId s = trace s s++-- | Similar to 'undefined' but data type.+{-# WARNING Undefined "'Undefined' type remains in code" #-}+data Undefined = Undefined+ deriving (P.Eq, P.Ord, P.Show, P.Read, P.Enum, P.Bounded, Data, Typeable, Generic)++-- | 'P.undefined' that leaves warning in code on every usage.+{-# WARNING undefined "'undefined' function remains in code (or use 'error')" #-}+#if ( __GLASGOW_HASKELL__ >= 800 )+undefined :: forall (r :: RuntimeRep) . forall (a :: TYPE r) . HasCallStack => a+#else+undefined :: a+#endif+undefined = P.undefined
+ src/Universum/DeepSeq.hs view
@@ -0,0 +1,32 @@+module Universum.DeepSeq+ ( module Control.DeepSeq+ , evaluateNF+ , evaluateNF_+ , evaluateWHNF+ , evaluateWHNF_+ ) where++import Control.DeepSeq (NFData (..), deepseq, force, ($!!))++import Universum.Base (seq)+import Universum.Function ((.))+import Universum.Monad (MonadIO, liftIO, (<$!>))++import qualified Control.Exception.Base (evaluate)++-- | Lifted alias for 'Control.Exception.Base.evaluate' with clearer name.+evaluateWHNF :: MonadIO m => a -> m a+evaluateWHNF = liftIO . Control.Exception.Base.evaluate++-- | Like 'evaluateWNHF' but discards value.+evaluateWHNF_ :: MonadIO m => a -> m ()+evaluateWHNF_ what = (`seq` ()) <$!> evaluateWHNF what++-- | Alias for @evaluateWHNF . force@ with clearer name.+evaluateNF :: (NFData a, MonadIO m) => a -> m a+evaluateNF = evaluateWHNF . force++-- | Alias for @evaluateWHNF . rnf@. Similar to 'evaluateNF'+-- but discards resulting value.+evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()+evaluateNF_ = evaluateWHNF . rnf
+ src/Universum/Exception.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Safe #-}++-- | Re-exports most useful functionality from 'safe-exceptions'. Also+-- provides some functions to work with exceptions over 'MonadError'.++module Universum.Exception+ ( module Control.Exception.Safe+ , note+ ) where++-- 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)++-- To suppress redundant applicative constraint warning on GHC 8.0+-- | Throws error for 'Maybe' if 'Data.Maybe.Nothing' is given.+-- Operates over 'MonadError'.+#if ( __GLASGOW_HASKELL__ >= 800 )+note :: (MonadError e m) => e -> Maybe a -> m a+note err = maybe (throwError err) pure+#else+note :: (MonadError e m, Applicative m) => e -> Maybe a -> m a+note err = maybe (throwError err) pure+#endif
+ src/Universum/Function.hs view
@@ -0,0 +1,10 @@+module Universum.Function+ ( module Data.Function+ , identity+ ) where++import Data.Function (const, fix, flip, on, ($), (.))++-- | Renamed version of 'Prelude.id'.+identity :: a -> a+identity x = x
+ src/Universum/Functor.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE Safe #-}++-- | Convenient functions to work with 'Functor'.++module Universum.Functor+ ( module Universum.Functor.Fmap+ , module Universum.Functor.Reexport+ ) where++import Universum.Functor.Fmap+import Universum.Functor.Reexport
+ src/Universum/Functor/Fmap.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE Safe #-}++module Universum.Functor.Fmap+ ( map+ , (<<$>>)+ ) where++import Universum.Function ((.))+import Universum.Functor.Reexport (Functor (..))++-- | 'Prelude.map' generalized to 'Functor'.+map :: Functor f => (a -> b) -> f a -> f b+map = fmap++-- | Alias for @fmap . fmap@. Convenient to work with two nested 'Functor's.+--+-- >>> negate <<$>> Just [1,2,3]+-- Just [-1,-2,-3]+(<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)+(<<$>>) = fmap . fmap+infixl 4 <<$>>
+ src/Universum/Functor/Reexport.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE Safe #-}++module Universum.Functor.Reexport+ ( module Control.Arrow+ , module Data.Bifunctor+ , module Data.Functor+ , module Data.Functor.Identity+ ) where++import Control.Arrow ((&&&))+import Data.Bifunctor (Bifunctor (..))+import Data.Functor (Functor (..), void, ($>), (<$>))+import Data.Functor.Identity (Identity (..))
+ src/Universum/Lifted.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE Safe #-}++-- | Lifted versions of base functions.++module Universum.Lifted+ ( module Universum.Lifted.Concurrent+ , module Universum.Lifted.Env+ , module Universum.Lifted.File+ , module Universum.Lifted.IORef+ , module Universum.Lifted.ST+ ) where++import Universum.Lifted.Concurrent+import Universum.Lifted.Env+import Universum.Lifted.File+import Universum.Lifted.IORef+import Universum.Lifted.ST
+ src/Universum/Lifted/Concurrent.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE Safe #-}++-- | Concurrency useful and common functions.++module Universum.Lifted.Concurrent+ ( -- * MVar+ MVar+ , newEmptyMVar+ , newMVar+ , putMVar+ , readMVar+ , swapMVar+ , takeMVar+ , tryPutMVar+ , tryReadMVar+ , tryTakeMVar++ -- * STM+ , STM+ , TVar+ , atomically+ , newTVarIO+ , readTVarIO+ , STM.modifyTVar'+ , STM.newTVar+ , STM.readTVar+ , STM.writeTVar+ ) where++import Control.Concurrent.MVar (MVar)+import Control.Concurrent.STM.TVar (TVar)+import Control.Monad.STM (STM)+import Control.Monad.Trans (MonadIO, liftIO)+import Data.Bool (Bool)+import Data.Function (($), (.))+import Data.Maybe (Maybe)++import qualified Control.Concurrent.MVar as CCM (newEmptyMVar, newMVar, putMVar, readMVar, swapMVar,+ takeMVar, tryPutMVar, tryReadMVar, tryTakeMVar)+import qualified Control.Concurrent.STM.TVar as STM (modifyTVar', newTVar, newTVarIO, readTVar,+ readTVarIO, writeTVar)+import qualified Control.Monad.STM as STM (atomically)++----------------------------------------------------------------------------+-- Lifted Control.Concurrent.MVar+----------------------------------------------------------------------------++-- | Lifted to 'MonadIO' version of 'CCM.newEmptyMVar'.+newEmptyMVar :: MonadIO m => m (MVar a)+newEmptyMVar = liftIO CCM.newEmptyMVar+{-# INLINE newEmptyMVar #-}++-- | Lifted to 'MonadIO' version of 'CCM.newMVar'.+newMVar :: MonadIO m => a -> m (MVar a)+newMVar = liftIO . CCM.newMVar+{-# INLINE newMVar #-}++-- | Lifted to 'MonadIO' version of 'CCM.putMVar'.+putMVar :: MonadIO m => MVar a -> a -> m ()+putMVar m a = liftIO $ CCM.putMVar m a+{-# INLINE putMVar #-}++-- | Lifted to 'MonadIO' version of 'CCM.readMVar'.+readMVar :: MonadIO m => MVar a -> m a+readMVar = liftIO . CCM.readMVar+{-# INLINE readMVar #-}++-- | Lifted to 'MonadIO' version of 'CCM.swapMVar'.+swapMVar :: MonadIO m => MVar a -> a -> m a+swapMVar m v = liftIO $ CCM.swapMVar m v+{-# INLINE swapMVar #-}++-- | Lifted to 'MonadIO' version of 'CCM.takeMVar'.+takeMVar :: MonadIO m => MVar a -> m a+takeMVar = liftIO . CCM.takeMVar+{-# INLINE takeMVar #-}++-- | Lifted to 'MonadIO' version of 'CCM.tryPutMVar'.+tryPutMVar :: MonadIO m => MVar a -> a -> m Bool+tryPutMVar m v = liftIO $ CCM.tryPutMVar m v+{-# INLINE tryPutMVar #-}++-- | Lifted to 'MonadIO' version of 'CCM.tryReadMVar'.+tryReadMVar :: MonadIO m => MVar a -> m (Maybe a)+tryReadMVar = liftIO . CCM.tryReadMVar+{-# INLINE tryReadMVar #-}++-- | Lifted to 'MonadIO' version of 'CCM.tryTakeMVar'.+tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a)+tryTakeMVar = liftIO . CCM.tryTakeMVar+{-# INLINE tryTakeMVar #-}++----------------------------------------------------------------------------+-- Lifted STM+----------------------------------------------------------------------------++-- | Lifted to 'MonadIO' version of 'STM.atomically'.+atomically :: MonadIO m => STM a -> m a+atomically = liftIO . STM.atomically+{-# INLINE atomically #-}++-- | Lifted to 'MonadIO' version of 'STM.newTVarIO'.+newTVarIO :: MonadIO m => a -> m (TVar a)+newTVarIO = liftIO . STM.newTVarIO+{-# INLINE newTVarIO #-}++-- | Lifted to 'MonadIO' version of 'STM.readTVarIO'.+readTVarIO :: MonadIO m => TVar a -> m a+readTVarIO = liftIO . STM.readTVarIO+{-# INLINE readTVarIO #-}
+ src/Universum/Lifted/Env.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE Safe #-}++-- | Lifted versions of functions that work with environment.++module Universum.Lifted.Env+ ( getArgs+ , exitWith+ , exitFailure+ , exitSuccess+ , die+ ) where++import Control.Monad.Trans (MonadIO, liftIO)+import Data.String (String)+import Prelude ((>>))+import System.Exit (ExitCode)+import System.IO (stderr)++import qualified System.Environment as XIO+import qualified System.Exit as XIO+import qualified System.IO (hPutStrLn)++-- | Lifted version of 'System.Environment.getArgs'.+getArgs :: MonadIO m => m [String]+getArgs = liftIO (XIO.getArgs)+{-# INLINE getArgs #-}++-- | Lifted version of 'System.Exit.exitWith'.+exitWith :: MonadIO m => ExitCode -> m a+exitWith a = liftIO (XIO.exitWith a)+{-# INLINE exitWith #-}++-- | Lifted version of 'System.Exit.exitFailure'.+exitFailure :: MonadIO m => m a+exitFailure = liftIO XIO.exitFailure+{-# INLINE exitFailure #-}++-- | Lifted version of 'System.Exit.exitSuccess'.+exitSuccess :: MonadIO m => m a+exitSuccess = liftIO XIO.exitSuccess+{-# INLINE exitSuccess #-}++-- | Lifted version of 'System.Exit.die'.+-- 'XIO.die' is available since base-4.8, but it's more convenient to+-- redefine it instead of using CPP.+die :: MonadIO m => String -> m ()+die err = liftIO (System.IO.hPutStrLn stderr err) >> exitFailure+{-# INLINE die #-}
+ src/Universum/Lifted/File.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE Safe #-}++-- | Lifted versions of functions working with files and common IO.+-- All functions are specialized to 'Data.Text.Text'.++module Universum.Lifted.File+ ( appendFile+ , getContents+ , getLine+ , interact+ , openFile+ , readFile+ , writeFile+ ) where++import Control.Monad.Trans (MonadIO, liftIO)+import Data.Text (Text)+import Prelude (FilePath)+import System.IO (Handle, IOMode)++import qualified Data.Text.IO as XIO+import qualified Data.Text.Lazy as L (Text)+import qualified Data.Text.Lazy.IO as LIO (getContents, interact)+import qualified System.IO as XIO (openFile)++----------------------------------------------------------------------------+-- Text+----------------------------------------------------------------------------++-- | Lifted version of 'Data.Text.appendFile'.+appendFile :: MonadIO m => FilePath -> Text -> m ()+appendFile a b = liftIO (XIO.appendFile a b)+{-# INLINE appendFile #-}++-- | Lifted version of 'Data.Text.getContents'.+getContents :: MonadIO m => m L.Text+getContents = liftIO LIO.getContents+{-# INLINE getContents #-}++-- | Lifted version of 'Data.Text.getLine'.+getLine :: MonadIO m => m Text+getLine = liftIO XIO.getLine+{-# INLINE getLine #-}++-- | Lifted version of 'Data.Text.interact'.+interact :: MonadIO m => (L.Text -> L.Text) -> m ()+interact a = liftIO (LIO.interact a)+{-# INLINE interact #-}++-- | Lifted version of 'Data.Text.readFile'.+readFile :: MonadIO m => FilePath -> m Text+readFile a = liftIO (XIO.readFile a)+{-# INLINE readFile #-}++-- | Lifted version of 'Data.Text.writeFile'.+writeFile :: MonadIO m => FilePath -> Text -> m ()+writeFile a b = liftIO (XIO.writeFile a b)+{-# INLINE writeFile #-}++-- | Lifted version of 'System.IO.openFile'.+openFile :: MonadIO m => FilePath -> IOMode -> m Handle+openFile a b = liftIO (XIO.openFile a b)+{-# INLINE openFile #-}++-- 'withFile' can't be lifted into 'MonadIO', as it uses 'bracket'
+ src/Universum/Lifted/IORef.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE Safe #-}++-- | Lifted reexports from 'Data.IORef' module.++module Universum.Lifted.IORef+ ( IORef+ , atomicModifyIORef+ , atomicModifyIORef'+ , atomicWriteIORef+ , modifyIORef+ , modifyIORef'+ , newIORef+ , readIORef+ , writeIORef+ ) where++import Control.Monad.Trans (MonadIO, liftIO)+import Data.Function (($), (.))+import Data.IORef (IORef)++import qualified Data.IORef as Ref (atomicModifyIORef, atomicModifyIORef', atomicWriteIORef,+ modifyIORef, modifyIORef', newIORef, readIORef, writeIORef)++-- | Lifted version of 'Ref.newIORef'.+newIORef :: MonadIO m => a -> m (IORef a)+newIORef = liftIO . Ref.newIORef+{-# INLINE newIORef #-}++-- | Lifted version of 'Ref.readIORef'.+readIORef :: MonadIO m => IORef a -> m a+readIORef = liftIO . Ref.readIORef+{-# INLINE readIORef #-}++-- | Lifted version of 'Ref.writeIORef'.+writeIORef :: MonadIO m => IORef a -> a -> m ()+writeIORef ref what = liftIO $ Ref.writeIORef ref what+{-# INLINE writeIORef #-}++-- | Lifted version of 'Ref.modifyIORef'.+modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()+modifyIORef ref how = liftIO $ Ref.modifyIORef ref how+{-# INLINE modifyIORef #-}++-- | Lifted version of 'Ref.modifyIORef''.+modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()+modifyIORef' ref how = liftIO $ Ref.modifyIORef' ref how+{-# INLINE modifyIORef' #-}++-- | Lifted version of 'Ref.atomicModifyIORef'.+atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b+atomicModifyIORef ref how = liftIO $ Ref.atomicModifyIORef ref how+{-# INLINE atomicModifyIORef #-}++-- | Lifted version of 'Ref.atomicModifyIORef''.+atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b+atomicModifyIORef' ref how = liftIO $ Ref.atomicModifyIORef' ref how+{-# INLINE atomicModifyIORef' #-}++-- | Lifted version of 'Ref.atomicWriteIORef'.+atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()+atomicWriteIORef ref what = liftIO $ Ref.atomicWriteIORef ref what+{-# INLINE atomicWriteIORef #-}
+ src/Universum/Lifted/ST.hs view
@@ -0,0 +1,12 @@+module Universum.Lifted.ST+ ( stToIO+ ) where++import Control.Monad.Trans (MonadIO, liftIO)++import qualified Control.Monad.ST as XIO++-- | Lifted version of 'XIO.stToIO'.+stToIO :: MonadIO m => XIO.ST XIO.RealWorld a -> m a+stToIO a = liftIO (XIO.stToIO a)+{-# INLINE stToIO #-}
+ src/Universum/List.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE Safe #-}++-- | Utility functions to work with lists.++module Universum.List+ ( module Universum.List.Reexport+ , module Universum.List.Safe+ ) where++import Universum.List.Reexport+import Universum.List.Safe
+ src/Universum/List/Reexport.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE Trustworthy #-}++module Universum.List.Reexport+ ( module Data.List++#if ( __GLASGOW_HASKELL__ >= 800 )+ , module Data.List.NonEmpty+#endif++ , module GHC.Exts+ ) 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, sortOn, splitAt, subsequences, tails, take, takeWhile,+ transpose, unfoldr, unzip, unzip3, zip, zip3, zipWith)++#if ( __GLASGOW_HASKELL__ >= 800 )+import Data.List.NonEmpty (head, init, last, tail)+#endif++import GHC.Exts (sortWith)
+ src/Universum/List/Safe.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE Trustworthy #-}++module Universum.List.Safe+ ( list+ , uncons+#if ( __GLASGOW_HASKELL__ >= 800 )+ , whenNotNull+ , whenNotNullM+#endif+ ) where++#if ( __GLASGOW_HASKELL__ >= 800 )+import Universum.Applicative (Applicative, pass)+import Universum.Monad (Monad (..))+import Universum.Monoid (NonEmpty (..))+#endif++import Universum.Functor (fmap)+import Universum.Monad (Maybe (..))++-- | Returns default list if given list is empty.+-- Otherwise applies given function to every element.+--+-- >>> list [True] even []+-- [True]+-- >>> list [True] even [1..5]+-- [False,True,False,True,False]+list :: [b] -> (a -> b) -> [a] -> [b]+list def f xs = case xs of+ [] -> def+ _ -> fmap f xs++-- | Destructuring list into its head and tail if possible. This function is total.+--+-- >>> uncons []+-- Nothing+-- >>> uncons [1..5]+-- Just (1,[2,3,4,5])+-- >>> uncons (5 : [1..5]) >>= \(f, l) -> pure $ f == length l+-- Just True+uncons :: [a] -> Maybe (a, [a])+uncons [] = Nothing+uncons (x:xs) = Just (x, xs)++#if ( __GLASGOW_HASKELL__ >= 800 )+-- | Performs given action over 'NonEmpty' list if given list is non empty.+whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()+whenNotNull [] _ = pass+whenNotNull (x:xs) f = f (x :| xs)+{-# INLINE whenNotNull #-}++-- | Monadic version of 'whenNotNull'.+whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m ()+whenNotNullM ml f = ml >>= \l -> whenNotNull l f+{-# INLINE whenNotNullM #-}+#endif
+ src/Universum/Monad.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE Trustworthy #-}++-- | Reexporting useful monadic stuff.++module Universum.Monad+ ( module Universum.Monad.Container+ , module Universum.Monad.Either+ , module Universum.Monad.Maybe+ , module Universum.Monad.Reexport+ , module Universum.Monad.Trans+ ) where++import Universum.Monad.Container+import Universum.Monad.Either+import Universum.Monad.Maybe+import Universum.Monad.Reexport+import Universum.Monad.Trans
+ src/Universum/Monad/Container.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE TypeFamilies #-}++module Universum.Monad.Container+ ( concatMapM+ , concatForM++ , allM+ , anyM+ , andM+ , orM+ ) where++import Control.Applicative (Applicative (pure))+import Data.Function ((.))+import Data.Traversable (Traversable (traverse))+import Prelude (Bool (..), Monoid, flip)++import Universum.Base (IO)+import Universum.Container (Container, Element, fold, toList)+import Universum.Functor (fmap)+import Universum.Monad.Reexport (Monad (..))++-- | Lifting bind into a monad. Generalized version of @concatMap@+-- that works with a monadic predicate. Old and simpler specialized to list+-- version had next type:+--+-- @+-- concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b]+-- @+--+-- Side note: previously it had type+--+-- @+-- concatMapM :: (Applicative q, Monad m, Traversable m)+-- => (a -> q (m b)) -> m a -> q (m b)+-- @+--+-- Such signature didn't allow to use this function when traversed container+-- type and type of returned by function-argument differed.+-- Now you can use it like e.g.+--+-- @+-- concatMapM readFile files >>= putStrLn+-- @+concatMapM+ :: ( Applicative f+ , Monoid m+ , Container (l m)+ , Element (l m) ~ m+ , Traversable l+ )+ => (a -> f m) -> l a -> f m+concatMapM f = fmap fold . traverse f+{-# INLINE concatMapM #-}++-- | Like 'concatMapM', but has its arguments flipped, so can be used+-- instead of the common @fmap concat $ forM@ pattern.+concatForM+ :: ( Applicative f+ , Monoid m+ , Container (l m)+ , Element (l m) ~ m+ , Traversable l+ )+ => l a -> (a -> f m) -> f m+concatForM = flip concatMapM+{-# INLINE concatForM #-}++-- | Monadic and constrained to 'Container' version of 'Prelude.and'.+--+-- >>> andM [Just True, Just False]+-- Just False+-- >>> andM [Just True]+-- Just True+-- >>> andM [Just True, Just False, Nothing]+-- Just False+-- >>> andM [Just True, Nothing]+-- Nothing+-- >>> andM [putStrLn "1" >> pure True, putStrLn "2" >> pure False, putStrLn "3" >> undefined]+-- 1+-- 2+-- False+andM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool+andM = go . toList+ where+ go [] = pure True+ go (p:ps) = do+ q <- p+ if q then go ps else pure False++-- | Monadic and constrained to 'Container' version of 'Prelude.or'.+--+-- >>> orM [Just True, Just False]+-- Just True+-- >>> orM [Just True, Nothing]+-- Just True+-- >>> orM [Nothing, Just True]+-- Nothing+orM :: (Container f, Element f ~ m Bool, Monad m) => f -> m Bool+orM = go . toList+ where+ go [] = pure False+ go (p:ps) = do+ q <- p+ if q then pure True else go ps++-- | Monadic and constrained to 'Container' version of 'Prelude.all'.+--+-- >>> allM (readMaybe >=> pure . even) ["6", "10"]+-- Just True+-- >>> allM (readMaybe >=> pure . even) ["5", "aba"]+-- Just False+-- >>> allM (readMaybe >=> pure . even) ["aba", "10"]+-- Nothing+allM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool+allM p = go . toList+ where+ go [] = pure True+ go (x:xs) = do+ q <- p x+ if q then go xs else pure False++-- | Monadic and constrained to 'Container' version of 'Prelude.any'.+--+-- >>> anyM (readMaybe >=> pure . even) ["5", "10"]+-- Just True+-- >>> anyM (readMaybe >=> pure . even) ["10", "aba"]+-- Just True+-- >>> anyM (readMaybe >=> pure . even) ["aba", "10"]+-- Nothing+anyM :: (Container f, Monad m) => (Element f -> m Bool) -> f -> m Bool+anyM p = go . toList+ where+ go [] = pure False+ go (x:xs) = do+ q <- p x+ if q then pure True else go xs++{-# SPECIALIZE andM :: [IO Bool] -> IO Bool #-}+{-# SPECIALIZE orM :: [IO Bool] -> IO Bool #-}+{-# SPECIALIZE anyM :: (a -> IO Bool) -> [a] -> IO Bool #-}+{-# SPECIALIZE allM :: (a -> IO Bool) -> [a] -> IO Bool #-}
+ src/Universum/Monad/Either.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE Safe #-}++-- | Utilites to work with @Either@ data type.++module Universum.Monad.Either+ ( fromLeft+ , fromRight+ , maybeToLeft+ , maybeToRight+ , leftToMaybe+ , rightToMaybe+ , whenLeft+ , whenLeftM+ , whenRight+ , whenRightM+ ) where++import Control.Applicative (Applicative)+import Control.Monad (Monad (..))+import Data.Function (const)+import Data.Maybe (Maybe (..), maybe)++import Universum.Applicative (pass)+import Universum.Monad.Reexport (Either (..), either)+++-- | 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)+-- Just True+-- >>> leftToMaybe (Right "aba")+-- Nothing+leftToMaybe :: Either l r -> Maybe l+leftToMaybe = either Just (const Nothing)++-- | Maps right part of 'Either' to 'Maybe'.+--+-- >>> rightToMaybe (Left True)+-- Nothing+-- >>> leftToMaybe (Right "aba")+-- Just "aba"+rightToMaybe :: Either l r -> Maybe r+rightToMaybe = either (const Nothing) Just++-- | Maps 'Maybe' to 'Either' wrapping default value into 'Left'.+--+-- >>> maybeToRight True (Just "aba")+-- Right "aba"+-- >>> maybeToRight True Nothing+-- Left True+maybeToRight :: l -> Maybe r -> Either l r+maybeToRight l = maybe (Left l) Right++-- | Maps 'Maybe' to 'Either' wrapping default value into 'Right'.+--+-- >>> maybeToLeft True (Just "aba")+-- Left "aba"+-- >>> maybeToRight True Nothing+-- Right True+maybeToLeft :: r -> Maybe l -> Either l r+maybeToLeft r = maybe (Right r) Left++-- | Applies given action to 'Either' content if 'Left' is given.+whenLeft :: Applicative f => Either l r -> (l -> f ()) -> f ()+whenLeft (Left l) f = f l+whenLeft (Right _) _ = pass+{-# INLINE whenLeft #-}++-- | Monadic version of 'whenLeft'.+whenLeftM :: Monad m => m (Either l r) -> (l -> m ()) -> m ()+whenLeftM me f = me >>= \e -> whenLeft e f+{-# INLINE whenLeftM #-}++-- | Applies given action to 'Either' content if 'Right' is given.+whenRight :: Applicative f => Either l r -> (r -> f ()) -> f ()+whenRight (Left _) _ = pass+whenRight (Right r) f = f r+{-# INLINE whenRight #-}++-- | Monadic version of 'whenRight'.+whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m ()+whenRightM me f = me >>= \e -> whenRight e f+{-# INLINE whenRightM #-}
+ src/Universum/Monad/Maybe.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE Safe #-}++-- | Utility functions to work with 'Data.Maybe' data type as monad.++module Universum.Monad.Maybe+ ( whenJust+ , whenJustM+ , whenNothing+ , whenNothing_+ , whenNothingM+ , whenNothingM_+ ) where++import Universum.Applicative (Applicative, pass, pure)+import Universum.Monad.Reexport (Maybe (..), Monad (..))++-- | 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>.+whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()+whenJust (Just x) f = f x+whenJust Nothing _ = pass+{-# INLINE whenJust #-}++-- | Monadic version of 'whenJust'.+whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()+whenJustM mm f = mm >>= \m -> whenJust m f+{-# INLINE whenJustM #-}++-- | Performs default 'Applicative' action if 'Nothing' is given.+-- Otherwise returns content of 'Just' pured to 'Applicative'.+--+-- >>> whenNothing Nothing [True, False]+-- [True,False]+-- >>> whenNothing (Just True) [True, False]+-- [True]+whenNothing :: Applicative f => Maybe a -> f a -> f a+whenNothing (Just x) _ = pure x+whenNothing Nothing m = m+{-# INLINE whenNothing #-}++-- | Performs default 'Applicative' action if 'Nothing' is given.+-- Do nothing for 'Just'. Convenient for discarding 'Just' content.+--+-- >>> whenNothing_ Nothing $ putText "Nothing!"+-- Nothing!+-- >>> whenNothing_ (Just True) $ putText "Nothing!"+whenNothing_ :: Applicative f => Maybe a -> f () -> f ()+whenNothing_ Nothing m = m+whenNothing_ _ _ = pass+{-# INLINE whenNothing_ #-}++-- | Monadic version of 'whenNothing'.+whenNothingM :: Monad m => m (Maybe a) -> m a -> m a+whenNothingM mm action = mm >>= \m -> whenNothing m action+{-# INLINE whenNothingM #-}++-- | Monadic version of 'whenNothingM_'.+whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m ()+whenNothingM_ mm action = mm >>= \m -> whenNothing_ m action+{-# INLINE whenNothingM_ #-}
+ src/Universum/Monad/Reexport.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE Trustworthy #-}++module Universum.Monad.Reexport+ ( -- * Reexport transformers+ module Control.Monad.Except+ , module Control.Monad.Reader+ , module Control.Monad.State.Strict+ , module Control.Monad.Trans+ , module Control.Monad.Trans.Identity+ , module Control.Monad.Trans.Maybe++ -- * Reexport Maybe+ , module Data.Maybe++ -- * Reexport Either+ , module Data.Either++ , Monad ((>>=), (>>), return)+ , MonadFail (fail)+ , MonadPlus (..)++ , (=<<)+ , (>=>)+ , (<=<)+ , forever++ , join+ , mfilter+ , filterM+ , mapAndUnzipM+ , zipWithM+ , zipWithM_+ , foldM+ , foldM_+ , replicateM+ , replicateM_++ , liftM2+ , liftM3+ , liftM4+ , liftM5+ , ap++ , (<$!>)+ ) 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, get, gets, modify, 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)++-- Maybe+import Data.Maybe (Maybe (..), catMaybes, fromMaybe, isJust, isNothing, listToMaybe, mapMaybe,+ maybe, maybeToList)++-- Either+import Data.Either (Either (..), either, isLeft, isRight, lefts, partitionEithers, rights)++import Control.Monad hiding (fail)++#if __GLASGOW_HASKELL__ >= 800+import Control.Monad.Fail (MonadFail (..))+#else+import Prelude (String)+import Text.ParserCombinators.ReadP (ReadP)+import Text.ParserCombinators.ReadPrec (ReadPrec)++import Universum.Base (IO)++import qualified Prelude as P (fail)++-- | Class for 'Monad's that can 'fail'.+-- Copied from 'fail' by Herbert Valerio Riedel (the library is under BSD3).+class Monad m => MonadFail m where+ fail :: String -> m a++instance MonadFail Maybe where+ fail _ = Nothing++instance MonadFail [] where+ fail _ = []++instance MonadFail IO where+ fail = P.fail++instance MonadFail ReadPrec where+ fail = P.fail -- = P (\_ -> fail s)++instance MonadFail ReadP where+ fail = P.fail+#endif
+ src/Universum/Monad/Trans.hs view
@@ -0,0 +1,67 @@+{-# LANGUAGE Safe #-}++-- | Monad transformers utilities.++module Universum.Monad.Trans+ ( -- * Convenient functions to work with 'Reader' monad+ usingReader+ , usingReaderT++ -- * Convenient functions to work with 'State' monad+ , evaluatingState+ , evaluatingStateT+ , executingState+ , executingStateT+ , usingState+ , usingStateT+ ) where++import Prelude (flip, fst, snd)++import Universum.Functor (Functor, (<$>))+import Universum.Monad.Reexport (Reader, ReaderT, State, StateT, runReader, runReaderT, runState,+ runStateT)++-- | Shorter and more readable alias for @flip runReaderT@.+usingReaderT :: r -> ReaderT r m a -> m a+usingReaderT = flip runReaderT+{-# INLINE usingReaderT #-}++-- | Shorter and more readable alias for @flip runReader@.+usingReader :: r -> Reader r a -> a+usingReader = flip runReader+{-# INLINE usingReader #-}++-- | Shorter and more readable alias for @flip runStateT@.+usingStateT :: s -> StateT s m a -> m (a, s)+usingStateT = flip runStateT+{-# INLINE usingStateT #-}++-- | Shorter and more readable alias for @flip runState@.+usingState :: s -> State s a -> (a, s)+usingState = flip runState+{-# INLINE usingState #-}++-- | Alias for @flip evalStateT@. It's not shorter but sometimes+-- more readable. Done by analogy with @using*@ functions family.+evaluatingStateT :: Functor f => s -> StateT s f a -> f a+evaluatingStateT s st = fst <$> usingStateT s st+{-# INLINE evaluatingStateT #-}++-- | Alias for @flip evalState@. It's not shorter but sometimes+-- more readable. Done by analogy with @using*@ functions family.+evaluatingState :: s -> State s a -> a+evaluatingState s st = fst (usingState s st)+{-# INLINE evaluatingState #-}++-- | Alias for @flip execStateT@. It's not shorter but sometimes+-- more readable. Done by analogy with @using*@ functions family.+executingStateT :: Functor f => s -> StateT s f a -> f s+executingStateT s st = snd <$> usingStateT s st+{-# INLINE executingStateT #-}++-- | Alias for @flip execState@. It's not shorter but sometimes+-- more readable. Done by analogy with @using*@ functions family.+executingState :: s -> State s a -> s+executingState s st = snd (usingState s st)+{-# INLINE executingState #-}
+ src/Universum/Monoid.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE CPP #-}++module Universum.Monoid+ (+#if ( __GLASGOW_HASKELL__ >= 800 )+ module Data.List.NonEmpty+ , module Data.Monoid+ , module Data.Semigroup+#else+ module Data.Monoid+#endif+ , maybeToMonoid+ ) where++import Data.Monoid (All (..), Alt (..), Any (..), Dual (..), Endo (..), First (..), Last (..),+ Monoid (..), Product (..), Sum (..))++#if ( __GLASGOW_HASKELL__ >= 800 )+import Data.List.NonEmpty (NonEmpty (..), nonEmpty)+import Data.Semigroup (Option (..), Semigroup (sconcat, stimes, (<>)), WrappedMonoid, cycle1,+ mtimesDefault, stimesIdempotent, stimesIdempotentMonoid, stimesMonoid)+#endif++import Universum.Monad.Reexport (Maybe, fromMaybe)++-- | 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
+ src/Universum/Nub.hs view
@@ -0,0 +1,77 @@+{-| Functions to remove duplicates from a list.++ = Performance+ To check the performance there was done a bunch of benchmarks.+ Benchmarks were made on lists of 'Prelude.Int's and 'Data.Text.Text's.+ There were two types of list to use:++ * Lists which consist of many different elements++ * Lists which consist of many same elements+++ Here are some recomendations for usage of particular functions based on benchmarking resutls.++ * 'hashNub' is faster than 'ordNub' when there're not so many different values in the list.++ * 'hashNub' is the fastest with 'Data.Text.Text'.++ * 'sortNub' has better performance than 'ordNub' but should be used when sorting is also needed.++ * 'unstableNub' has better performance than 'hashNub' but doesn't save the original order.+-}++module Universum.Nub+ ( hashNub+ , ordNub+ , sortNub+ , unstableNub+ ) where++import Data.Eq (Eq)+import Data.Hashable (Hashable)+import Data.HashSet as HashSet+import Data.Ord (Ord)+import Prelude ((.))++import qualified Data.Set as Set++-- | Like 'Prelude.nub' but runs in @O(n * log n)@ time and requires 'Ord'.+--+-- >>> ordNub [3, 3, 3, 2, 2, -1, 1]+-- [3, 2, -1, 1]+ordNub :: (Ord a) => [a] -> [a]+ordNub = go Set.empty+ where+ go _ [] = []+ go s (x:xs) =+ if x `Set.member` s+ then go s xs+ else x : go (Set.insert x s) xs++-- | Like 'Prelude.nub' but runs in @O(n * log_16(n))@ time and requires 'Hashable'.+--+-- >>> hashNub [3, 3, 3, 2, 2, -1, 1]+-- [3, 2, -1, 1]+hashNub :: (Eq a, Hashable a) => [a] -> [a]+hashNub = go HashSet.empty+ where+ go _ [] = []+ go s (x:xs) =+ if x `HashSet.member` s+ then go s xs+ else x : go (HashSet.insert x s) xs++-- | Like 'ordNub' but also sorts a list.+--+-- >>> sortNub [3, 3, 3, 2, 2, -1, 1]+-- [-1, 1, 2, 3]+sortNub :: (Ord a) => [a] -> [a]+sortNub = Set.toList . Set.fromList++-- | Like 'hashNub' but has better performance and also doesn't save the order.+--+-- >>> unstableNub [3, 3, 3, 2, 2, -1, 1]+-- [1, 2, 3, -1]+unstableNub :: (Eq a, Hashable a) => [a] -> [a]+unstableNub = HashSet.toList . HashSet.fromList
+ src/Universum/Print.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Trustworthy #-}++-- | Generalization of 'Prelude.putStr' and 'Prelude.putStrLn' functions.++module Universum.Print+ ( Print (..)+ , print+ , putText+ , putTextLn+ , putLText+ , putLTextLn+ ) where++import Data.Function ((.))++import Universum.Monad.Reexport (MonadIO, liftIO)++import qualified Prelude (print, putStr, putStrLn)++import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL++import qualified Data.Text as T+import qualified Data.Text.IO as T++import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.IO as TL++import qualified Universum.Base as Base++-- | Polymorfic over string and lifted to 'MonadIO' printing functions.+class Print a where+ putStr :: MonadIO m => a -> m ()+ putStrLn :: MonadIO m => a -> m ()++instance Print T.Text where+ putStr = liftIO . T.putStr+ putStrLn = liftIO . T.putStrLn++instance Print TL.Text where+ putStr = liftIO . TL.putStr+ putStrLn = liftIO . TL.putStrLn++instance Print BS.ByteString where+ putStr = liftIO . BS.putStr+ putStrLn = liftIO . BS.putStrLn++instance Print BL.ByteString where+ putStr = liftIO . BL.putStr+ putStrLn = liftIO . BL.putStrLn++instance Print [Base.Char] where+ putStr = liftIO . Prelude.putStr+ putStrLn = liftIO . Prelude.putStrLn++-- | Lifted version of 'Prelude.print'.+print :: forall a m . (MonadIO m, Base.Show a) => a -> m ()+print = liftIO . Prelude.print++-- | Specialized to 'T.Text' version of 'putStr' or forcing type inference.+putText :: MonadIO m => T.Text -> m ()+putText = putStr+{-# SPECIALIZE putText :: T.Text -> Base.IO () #-}++-- | Specialized to 'T.Text' version of 'putStrLn' or forcing type inference.+putTextLn :: MonadIO m => T.Text -> m ()+putTextLn = putStrLn+{-# SPECIALIZE putTextLn :: T.Text -> Base.IO () #-}++-- | Specialized to 'TL.Text' version of 'putStr' or forcing type inference.+putLText :: MonadIO m => TL.Text -> m ()+putLText = putStr+{-# SPECIALIZE putLText :: TL.Text -> Base.IO () #-}++-- | Specialized to 'TL.Text' version of 'putStrLn' or forcing type inference.+putLTextLn :: MonadIO m => TL.Text -> m ()+putLTextLn = putStrLn+{-# SPECIALIZE putLTextLn :: TL.Text -> Base.IO () #-}
+ src/Universum/String.hs view
@@ -0,0 +1,9 @@+-- | Type classes for convertion between different string representations.++module Universum.String+ ( module Universum.String.Conversion+ , module Universum.String.Reexport+ ) where++import Universum.String.Conversion+import Universum.String.Reexport
+ src/Universum/String/Conversion.hs view
@@ -0,0 +1,171 @@+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Universum.String.Conversion+ ( -- * Convenient type aliases+ LText+ , LByteString++ -- * Conversion type classes+ , ConvertUtf8 (..)+ , ToString (..)+ , ToLText (..)+ , ToText (..)++ -- * Show and read functions+ , readEither+ , show+ , pretty+ , prettyL+ ) where++import Data.Bifunctor (first)+import Data.Either (Either)+import Data.Function (id, (.))+import Data.String (String)+import Data.Text.Buildable (build)+import Data.Text.Lazy.Builder (toLazyText)++import Universum.Functor ((<$>))+import Universum.String.Reexport (Buildable, ByteString, IsString, Read, Text, fromString, toStrict)++import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as LB+import qualified Data.ByteString.Lazy.UTF8 as LBU+import qualified Data.ByteString.UTF8 as BU+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import qualified Data.Text.Encoding.Error as T+import qualified Data.Text.Lazy as LT+import qualified Data.Text.Lazy.Encoding as LT+import qualified Text.Read (readEither)++import qualified GHC.Show as Show (Show (show))++-- | Type synonym for 'Data.Text.Lazy.Text'.+type LText = LT.Text++-- | Type synonym for 'Data.ByteString.Lazy.ByteString'.+type LByteString = LB.ByteString+++-- | Type class for conversion to utf8 representation of text.+class ConvertUtf8 a b where+ -- | Encode as utf8 string (usually 'B.ByteString').+ --+ -- >>> encodeUtf8 @Text @ByteString "патак"+ -- "\208\191\208\176\209\130\208\176\208\186"+ encodeUtf8 :: a -> b++ -- | Decode from utf8 string.+ --+ -- >>> decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186"+ -- "\1087\1072\1090\1072\1082"+ -- >>> putStrLn $ decodeUtf8 @Text @ByteString "\208\191\208\176\209\130\208\176\208\186"+ -- патак+ decodeUtf8 :: b -> a++ -- | Decode as utf8 string but returning execption if byte sequence is malformed.+ --+ -- >>> decodeUtf8 @Text @ByteString "\208\208\176\209\130\208\176\208\186"+ -- "\65533\65533\1090\1072\1082"+ -- >>> decodeUtf8Strict @Text @ByteString "\208\208\176\209\130\208\176\208\186"+ -- Left Cannot decode byte '\xd0': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream+ decodeUtf8Strict :: b -> Either T.UnicodeException a++instance ConvertUtf8 String B.ByteString where+ encodeUtf8 = BU.fromString+ decodeUtf8 = BU.toString+ decodeUtf8Strict = (T.unpack <$>) . decodeUtf8Strict++instance ConvertUtf8 T.Text B.ByteString where+ encodeUtf8 = T.encodeUtf8+ decodeUtf8 = T.decodeUtf8With T.lenientDecode+ decodeUtf8Strict = T.decodeUtf8'++instance ConvertUtf8 LT.Text B.ByteString where+ encodeUtf8 = LB.toStrict . encodeUtf8+ decodeUtf8 = LT.decodeUtf8With T.lenientDecode . LB.fromStrict+ decodeUtf8Strict = decodeUtf8Strict . LB.fromStrict++instance ConvertUtf8 String LB.ByteString where+ encodeUtf8 = LBU.fromString+ decodeUtf8 = LBU.toString+ decodeUtf8Strict = (T.unpack <$>) . decodeUtf8Strict++instance ConvertUtf8 T.Text LB.ByteString where+ encodeUtf8 = LB.fromStrict . T.encodeUtf8+ decodeUtf8 = T.decodeUtf8With T.lenientDecode . LB.toStrict+ decodeUtf8Strict = T.decodeUtf8' . LB.toStrict++instance ConvertUtf8 LT.Text LB.ByteString where+ encodeUtf8 = LT.encodeUtf8+ decodeUtf8 = LT.decodeUtf8With T.lenientDecode+ decodeUtf8Strict = LT.decodeUtf8'++-- | Type class for converting other strings to 'T.Text'.+class ToText a where+ toText :: a -> T.Text++instance ToText String where+ toText = T.pack++instance ToText T.Text where+ toText = id++instance ToText LT.Text where+ toText = LT.toStrict++-- | Type class for converting other strings to 'LT.Text'.+class ToLText a where+ toLText :: a -> LT.Text++instance ToLText String where+ toLText = LT.pack++instance ToLText T.Text where+ toLText = LT.fromStrict++instance ToLText LT.Text where+ toLText = id++-- | Type class for converting other strings to 'String'.+class ToString a where+ toString :: a -> String++instance ToString String where+ toString = id++instance ToString T.Text where+ toString = T.unpack++instance ToString LT.Text where+ toString = LT.unpack++-- | Polymorhpic version of 'Text.Read.readEither'.+--+-- >>> readEither @Text @Int "123"+-- Right 123+-- >>> readEither @Text @Int "aa"+-- Left "Prelude.read: no parse"+readEither :: (ToString a, Read b) => a -> Either Text b+readEither = first toText . Text.Read.readEither . toString++-- | Generalized version of 'Prelude.show'.+show :: forall b a . (Show.Show a, IsString b) => a -> b+show x = fromString (Show.show x)+{-# SPECIALIZE show :: Show.Show a => a -> Text #-}+{-# SPECIALIZE show :: Show.Show a => a -> LText #-}+{-# SPECIALIZE show :: Show.Show a => a -> ByteString #-}+{-# SPECIALIZE show :: Show.Show a => a -> LByteString #-}+{-# SPECIALIZE show :: Show.Show a => a -> String #-}++-- | Functions to show pretty output for buildable data types.+pretty :: Buildable a => a -> Text+pretty = toStrict . prettyL++-- | Similar to 'pretty' but for 'LText'.+prettyL :: Buildable a => a -> LText+prettyL = toLazyText . build
+ src/Universum/String/Reexport.hs view
@@ -0,0 +1,27 @@+module Universum.String.Reexport+ ( -- * String+ module Data.String++ -- * Text+ , module Data.Text+ , module Data.Text.Lazy+ , module Data.Text.Encoding+ , module Data.Text.Encoding.Error+ , module Text.Read++ -- * ByteString+ , module Data.ByteString++ -- * Buildable+ , module Data.Text.Buildable+ ) where++import Data.ByteString (ByteString)+import Data.String (IsString (..))+import Data.Text (Text, lines, unlines, unwords, words)+import Data.Text.Buildable (Buildable)+import Data.Text.Encoding (decodeUtf8', decodeUtf8With)+import Data.Text.Encoding.Error (OnDecodeError, OnError, UnicodeException, lenientDecode,+ strictDecode)+import Data.Text.Lazy (fromStrict, toStrict)+import Text.Read (Read, readMaybe, reads)
+ src/Universum/TypeOps.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE ExplicitNamespaces #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}++#if __GLASGOW_HASKELL__ <= 710+{-# LANGUAGE Trustworthy #-}+#else+{-# LANGUAGE Safe #-}+#endif++-- | Type operators for writing convenient type signatures.++module Universum.TypeOps+ ( type Each+ , type With+ , type ($)+ ) where++#if __GLASGOW_HASKELL__ <= 710+import GHC.Prim (Constraint)+#else+import Data.Kind (Constraint)+#endif++import Control.Type.Operator (type ($), type (<+>))++-- | Map several constraints over several variables.+--+-- @+-- f :: Each [Show, Read] [a, b] => a -> b -> String+-- =+-- f :: (Show a, Show b, Read a, Read b) => a -> b -> String+-- @+--+-- To specify list with single constraint / variable, don't forget to prefix+-- it with @\'@:+--+-- @+-- f :: Each '[Show] [a, b] => a -> b -> String+-- @+type family Each (c :: [k -> Constraint]) (as :: [k]) where+ Each c '[] = (() :: Constraint)+ Each c (h ': t) = (c <+> h, Each c t)++-- | Map several constraints over a single variable.+-- Note, that @With a b ≡ Each a '[b]@+--+-- @+-- a :: With [Show, Read] a => a -> a+-- =+-- a :: (Show a, Read a) => a -> a+-- @+type With a b = a <+> b
+ src/Universum/VarArg.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE IncoherentInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++-- | Provides operator of variable-arguments function composition.++module Universum.VarArg+ ( SuperComposition(..)+ ) where++class SuperComposition a b c | a b -> c where+ -- | Allows to apply function to result of another function with multiple+ -- arguments.+ --+ -- >>> (show ... (+)) 1 2+ -- "3"+ -- >>> show ... 5+ -- "5"+ -- >>> (null ... zip5) [1] [2] [3] [] [5]+ -- True+ --+ -- Inspired by <http://stackoverflow.com/questions/9656797/variadic-compose-function>.+ --+ -- ==== Performance+ -- To check the performance there was done a bunch of benchmarks. Benchmarks were made on+ -- examples given above and also on the functions of many arguments.+ -- The results are showing that the operator ('...') performs as fast as+ -- plain applications of the operator ('Prelude..') on almost all the tests, but ('...')+ -- leads to the performance draw-down if @ghc@ fails to inline it.+ -- Slow behavior was noticed on functions without type specifications.+ -- That's why keep in mind that providing explicit type declarations for functions is very+ -- important when using ('...').+ -- Relying on type inference will lead to the situation when all optimizations+ -- disappear due to very general inferred type. However, functions without type+ -- specification but with applied @INLINE@ pragma are fast again.+ --+ (...) :: a -> b -> c++infixl 8 ...++instance (a ~ c, r ~ b) =>+ SuperComposition (a -> b) c r where+ f ... g = f g+ {-# INLINE (...) #-}++instance (SuperComposition (a -> b) d r1, r ~ (c -> r1)) =>+ SuperComposition (a -> b) (c -> d) r where+ (f ... g) c = f ... g c+ {-# INLINE (...) #-}
− src/Unsafe.hs
@@ -1,42 +0,0 @@-{-# LANGUAGE Unsafe #-}---- | Unsafe functions to work with lists and 'Maybe'.--- Sometimes unavoidable but better don't use them. This module--- is not even included in default prelude exports.--module Unsafe- ( unsafeHead- , unsafeTail- , unsafeInit- , unsafeLast- , unsafeFromJust- , unsafeIndex- ) where--import Base (Int)-import qualified Data.List as List-import qualified Data.Maybe as Maybe---- | Cautionary alias for 'List.head'.-unsafeHead :: [a] -> a-unsafeHead = List.head---- | Cautionary alias for 'List.tail'.-unsafeTail :: [a] -> [a]-unsafeTail = List.tail---- | Cautionary alias for 'List.init'.-unsafeInit :: [a] -> [a]-unsafeInit = List.init---- | Cautionary alias for 'List.last'.-unsafeLast :: [a] -> a-unsafeLast = List.last---- | Cautionary alias for 'List.!!'.-unsafeIndex :: [a] -> Int -> a-unsafeIndex = (List.!!)---- | Cautionary alias for 'Maybe.fromJust'.-unsafeFromJust :: Maybe.Maybe a -> a-unsafeFromJust = Maybe.fromJust
− src/VarArg.hs
@@ -1,52 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE IncoherentInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}---- | Provides operator of variable-arguments function composition.--module VarArg- ( SuperComposition(..)- ) where--class SuperComposition a b c | a b -> c where- -- | Allows to apply function to result of another function with multiple- -- arguments.- --- -- >>> (show ... (+)) 1 2- -- "3"- -- >>> show ... 5- -- "5"- -- >>> (null ... zip5) [1] [2] [3] [] [5]- -- True- --- -- Inspired by <http://stackoverflow.com/questions/9656797/variadic-compose-function>.- --- -- ==== Performance- -- To check the performance there was done a bunch of benchmarks. Benchmarks were made on- -- examples given above and also on the functions of many arguments.- -- The results are showing that the operator ('...') performs as fast as- -- plain applications of the operator ('Prelude..') on almost all the tests, but ('...')- -- leads to the performance draw-down if @ghc@ fails to inline it.- -- Slow behavior was noticed on functions without type specifications.- -- That's why keep in mind that providing explicit type declarations for functions is very- -- important when using ('...').- -- Relying on type inference will lead to the situation when all optimizations- -- disappear due to very general inferred type. However, functions without type- -- specification but with applied @INLINE@ pragma are fast again.- --- (...) :: a -> b -> c--infixl 8 ...--instance (a ~ c, r ~ b) =>- SuperComposition (a -> b) c r where- f ... g = f g- {-# INLINE (...) #-}--instance (SuperComposition (a -> b) d r1, r ~ (c -> r1)) =>- SuperComposition (a -> b) (c -> d) r where- (f ... g) c = f ... g c- {-# INLINE (...) #-}
universum.cabal view
@@ -1,12 +1,12 @@ name: universum-version: 0.9.2+version: 1.0.0 cabal-version: >=1.10 build-type: Simple license: MIT license-file: LICENSE-copyright: 2016-2016 Stephen Diehl, 2016-2017 Serokell+copyright: 2016 Stephen Diehl, 2016-2017 Serokell maintainer: Serokell <hi@serokell.io>-stability: well...+stability: stable homepage: https://github.com/serokell/universum bug-reports: https://github.com/serokell/universum/issues synopsis: Custom prelude used in Serokell@@ -25,43 +25,54 @@ library exposed-modules: Universum- Applicative- Base- Bool- Container- Container.Class- Container.Reexport- Debug- Exceptions- Functor- List- Nub- Print- String- TypeOps- Unsafe- VarArg- Lifted- Lifted.Concurrent- Lifted.Env- Lifted.File- Lifted.IORef- Monad- Monad.Either- Monad.Maybe- Monad.Trans+ Universum.Applicative+ Universum.Base+ Universum.Bool+ Universum.Bool.Guard+ Universum.Bool.Reexport+ Universum.Container+ Universum.Container.Class+ Universum.Container.Reexport+ Universum.Debug+ Universum.DeepSeq+ Universum.Exception+ Universum.Function+ Universum.Functor+ Universum.Functor.Fmap+ Universum.Functor.Reexport+ Universum.Lifted+ Universum.Lifted.Concurrent+ Universum.Lifted.Env+ Universum.Lifted.File+ Universum.Lifted.IORef+ Universum.Lifted.ST+ Universum.List+ Universum.List.Reexport+ Universum.List.Safe+ Universum.Monad+ Universum.Monad.Container+ Universum.Monad.Either+ Universum.Monad.Maybe+ Universum.Monad.Reexport+ Universum.Monad.Trans+ Universum.Monoid+ Universum.Nub+ Universum.Print+ Universum.String+ Universum.String.Conversion+ Universum.String.Reexport+ Universum.TypeOps+ Universum.VarArg build-depends:- base >=4.9.1.0 && <5,+ base >=4.8 && <5, bytestring >=0.10.8.1, containers >=0.5.7.1, deepseq >=1.4.2.0,- exceptions >=0.8.3, ghc-prim >=0.5.0.0, hashable >=1.2.6.1, microlens >=0.4.8.1, microlens-mtl >=0.1.11.0, mtl >=2.2.1,- safe >=0.3.15, safe-exceptions >=0.1.6.0, stm >=2.4.4.1, text >=1.2.2.2,