packages feed

universum 1.1.0 → 1.1.1

raw patch · 26 files changed

+397/−112 lines, 26 filesdep +gaugedep −criteriondep ~semigroups

Dependencies added: gauge

Dependencies removed: criterion

Dependency ranges changed: semigroups

Files

CHANGES.md view
@@ -1,3 +1,17 @@+1.1.1+=====++* [#148](https://github.com/serokell/universum/issues/148):+  Add `CODEOWNERS` and contributing guide.+* [#135](https://github.com/serokell/universum/issues/135):+  Add documentation regarding internal module structure.+* [#113](https://github.com/serokell/universum/issues/113):+  Annotate `at` function from `Unsafe` module and `ordNub`+  function from `Nub` module with `liquidhaskell`.+* [#73](https://github.com/serokell/universum/issues/73):+  Add more examples to docs and fix warnings where possible.+* Move reexport of `NonEmpty` to `Universum.List` module.+ 1.1.0 ===== 
+ CONTRIBUTING.md view
@@ -0,0 +1,46 @@+# Contributing to `universum`++## :wave: Greetings Traveler!++I'm glad you're reading this, I really appreciate the effort you're+putting in. Thank you for your help in making this library awesome! :sparkles:++### How to contribute++#### Report bugs or feature request+If you have found any bugs or have proposals on how to make this project better,+don't hesitate to create issues+[here](https://github.com/serokell/universum/issues/new) in free format.++#### Create a PR+We love receiving pull requests from everyone. But, please, don't create a PR+without a corresponding issue. It's always better to discuss your future+work first. Even if such an issue exist it's still better to express your willing+to do that issue under comment section. Thus you will show that you're doing+that issue, and nobody else will accidentally do it in parallel with you. Furthermore you+also can discuss the best way to implement that issue!++To get started with this you should first fork, then clone the repo:++    git clone git@github.com:your-username/universum.git++Make your changes and consider the following check list to go through before submitting your pull request.++#### :white_check_mark: Check list+- [ ] Project compiles+- [ ] New/fixed features work as expected+- [ ] Old features do not break after the change+- [ ] _Recommended:_ Commit messages are in the proper format. If the commit+  addresses an issue start the first line of the commit with the issue number in+  square parentheses.+  + **_Example:_** `[#42] Short commit description`++If you fix bugs or add new features, please add tests.++After everything above is done, commit and push to your fork.+Now you are ready to [submit a pull request][pr]!++----------+Thanks for spending time on reading this contributing guide! :sparkling_heart:++[pr]: https://github.com/serokell/universum/compare/
README.md view
@@ -8,11 +8,21 @@ [![Stackage Nightly](http://stackage.org/package/universum/badge/nightly)](http://stackage.org/nightly/package/universum) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -A custom prelude used in Serokell.+`universum` is a custom prelude used in @Serokell that has: -What is this?--------------+1. **Excellent documentation**: tutorial, migration guide from `Prelude`,+   Haddock with examples for (almost) every function,+   all examples are tested with [`doctest`](http://hackage.haskell.org/package/doctest),+   documenation regarding internal module structure.+2. `universum`-specific [HLint](http://hackage.haskell.org/package/hlint) rules:+   [`.hlint.yaml`](https://github.com/serokell/universum/blob/master/.hlint.yaml)+3. Only a few LiquidHaskell properties right now, but LiquidHaskell is on Travis+   CI and other properties are just waiting to be added!+4. Focus on safety, convenience and efficiency. +What is this file about?+------------------------+ This README contains introduction to `Universum` and a tutorial on how to use it.  Structure of this tutorial@@ -20,38 +30,38 @@  This tutorial has several parts: -1. Philosophy and motivation.-2. How to use `universum`.-3. Changes in `Prelude` (some gotchas).-4. Already known things that weren't in `Prelude` brought into scope.-5. New things added.+1. [Philosophy and motivation.](#why-another-custom-prelude-)+2. [How to use `universum`.](#how-to-use-universum-)+3. [Changes in `Prelude` (some gotchas).](#gotchas-)+4. [Already known things that weren't in `Prelude` brought into scope.](#things-that-you-were-already-using-but-now-you-dont-have-to-import-them-explicitly-)+5. [New things added.](#whats-new-)+6. [Migration guide from `Prelude`.](#migration-guide-from-prelude-) -This is not a tutorial on _Haskell_, and not even a tutorial on each function. For the detailed-documentation of every function with examples and usages see+This is neither a tutorial on _Haskell_ nor tutorial on each function contained in Universum. For detailed+documentation of every function together with examples and usage, see [_Haddock documentation_](http://hackage.haskell.org/package/universum). -Why another custom Prelude?+Why another custom Prelude? [↑](#structure-of-this-tutorial) ---------------------------  ### Motivation -In [Serokell](https://github.com/serokell/),  we want to be as much productive as possible.-That's why we are using [_Haskell_](https://haskell-lang.org/). This choice of language implies+At [Serokell](https://github.com/serokell/), we strive to be as productive as possible. That's why we are using [_Haskell_](https://haskell-lang.org/). This choice of language implies that we're restricted to use [`Prelude`](http://hackage.haskell.org/package/base-4.9.1.0/docs/Prelude.html):-implicit import of basic functions, type classes and data types. But the default `Prelude`+implicit import of basic functions, type classes and data types. Unfortunately, the default `Prelude` [is considered to be not so good](https://news.ycombinator.com/item?id=8002749) due to some historical reasons. -This is why we decided to use a better tool. Hopefully _Haskell_ provides us with ability-to replace default `Prelude` with some alternative. All we need to do is to implement-new basic set of defaults. But we don't intend to implement everything from scratch.-There're already plenty of [preludes](https://guide.aelve.com/haskell/alternative-preludes-zr69k1hc).-After some hot long discussions our team decided to base our custom prelude on+This is why we decided to use a better tool. Luckily, _Haskell_ provides us with the ability+to replace default `Prelude` with an alternative. All we had to do is to implement a+new basic set of defaults. There already were plenty of [preludes](https://guide.aelve.com/haskell/alternative-preludes-zr69k1hc), +so we didn't plan to implement everything from scratch.+After some long, hot discussions, our team decided to base our custom prelude on [`protolude`](https://github.com/sdiehl/protolude). If you're not familiar with it, you can read [a tutorial about `protolude`](http://www.stephendiehl.com/posts/protolude.html). -The next section explains why we have made this choice and what we are willing to do.-This tutorial doesn't cover the differences from `protolude`. Instead, it explains how Universum is different from custom `Prelude`.+The next section explains why we've made this choice and what we are willing to do.+This tutorial doesn't cover the differences from `protolude`. Instead, it explains how Universum is different from regular `Prelude`.  ### Main goals @@ -59,18 +69,17 @@  1. Avoid all [partial functions](https://www.reddit.com/r/haskell/comments/5n51u3/why_are_partial_functions_as_in_head_tail_bad/).    We like [total](http://mathworld.wolfram.com/TotalFunction.html) and exception-free functions.-   Though you can still use some unsafe functions from `Universum.Unsafe` module+   You can still use some unsafe functions from `Universum.Unsafe` module,    but they are not exported by default. 2. Use more efficient [string representations](https://www.reddit.com/r/haskell/comments/29jw0s/whats_wrong_with_string/).    `String` type is crushingly inefficient. All our functions either try to be polymorphic over string-   types, or use [`Text`](http://hackage.haskell.org/package/text-1.2.2.1/docs/Data-Text.html)-   as the default string type. `String` type alias is still reexported, because the community-   is evolving slowly, some libraries still use `String` type. But we recommend to avoid `String`!-3. Don't reinvent the wheel. We're not trying to rebuild whole type hierarchy from scratch,+   type or use [`Text`](http://hackage.haskell.org/package/text-1.2.2.1/docs/Data-Text.html)+   as the default string type. Because the community is evolving slowly, some libraries still use `String` type, so `String` type alias is still reexported. We recommend to avoid `String` as much as you can!+3. Try to not reinvent the wheel. We're not trying to rebuild whole type hierarchy from scratch,    as it's done in [`classy-prelude`](https://github.com/snoyberg/mono-traversable).    Instead, we reexport common and well-known things from `base` and some other-   libraries used in everyday production programming in _Haskell_.-   > **Note**: well, we did end up inventing something new.+   libraries that are used in everyday production programming in _Haskell_.+   > **Note**: well, we did end up inventing _some_ new things. 4. Export more useful and commonly used functions. [Hello, my name is Dmitry. I was    coding _Haskell_ for 3 years but still hoogling which module `liftIO` comes from.](https://twitter.com/magnars/status/834683466130345984)    Things like `liftIO`, `ReaderT` type, `MVar`-related functions have unambiguous names,@@ -86,8 +95,8 @@ 3. Trying to make writing production code easier (see    [enhancements and fixes](https://github.com/serokell/universum/issues)). -How to use Universum-----------+How to use Universum [↑](#structure-of-this-tutorial)+--------------------  Okay, enough philosophy. If you want to just start using `universum` and explore it with the help of compiler, set everything up according to the instructions below.@@ -110,12 +119,17 @@ import Universum ``` -If you're using [Emacs](https://www.gnu.org/software/emacs/), you can+If you're using [Emacs](https://www.gnu.org/software/emacs/) and don't want to+type `import Universum` manually every time, you can [modify your configs](https://github.com/serokell/universum/issues/8#issuecomment-276444879)-a little bit if you don't want to type `import Universum` manually every time.+a little bit. +If you want to get familiar with `universum` internal structure, you can just+read top-level documentation for+[`Universum`](http://hackage.haskell.org/package/universum/docs/Universum.html)+module. -Gotchas+Gotchas [↑](#structure-of-this-tutorial) -------  * `head`, `tail`, `last`, `init` work with `NonEmpty a` instead of `[a]`.@@ -148,8 +162,8 @@ * `error` takes `Text`.  -Things that you were already using, but now you don't have to import them explicitly---------------------------------------------------------------------------+Things that you were already using, but now you don't have to import them explicitly [↑](#structure-of-this-tutorial)+------------------------------------------------------------------------------------  ### Commonly used libraries @@ -194,7 +208,7 @@ module explicitly. Instead use functionality from `safe-exceptions` provided by `universum` or import `Control.Exceptions.Safe` module. -What's new?+What's new? [↑](#structure-of-this-tutorial) -----------  Finally, we can move to part describing the new cool features we bring with `universum`.@@ -281,7 +295,58 @@   `evaluate` and `evaluate . force`. * `ToPairs` type class for data types that can be converted to list of pairs (like `Map` or `HashMap` or `IntMap`). -Projects that use Universum+Migration guide from Prelude [↑](#structure-of-this-tutorial)+----------------------------++In order to replace default `Prelude` with `universum` you should start with instructions given in+[how to use universum](https://github.com/serokell/universum#how-to-use-universum-) section.++This section describes what you need to change to make your code compile with `universum`.++1. Enable `-XOverloadedStrings` and `-XTypeFamilies` extension by default for your project.+2. Since `head`, `tail`, `last` and `init` work for `NonEmpty` you should+   refactor your code in one of the multiple ways described below:+   1. Change `[a]` to `NonEmpty a` where it makes sense.+   2. Use functions which return `Maybe`. They can be implemented using `nonEmpty` function. Like `head <$> nonEmpty l`.+       + `head <$> nonEmpty l` is `safeHead l`+       + `tail` is `drop 1`. It's almost never a good idea to use `tail` from `Prelude`.+   3. Add `import qualified Universum.Unsafe as Unsafe` and replace function with qualified usage.+3. If you use `fromJust` or `!!` you should use them from `import qualified Universum.Unsafe as Unsafe`.+4. Derive or implement `Container` instances for your data types which implement+   `Foldable` instances. This can be done in a single line because `Container`+   type class automatically derives from `Foldable`.+5. `Container` type class from `universum` replaces `Foldable` and doesn't have+   instances for `Maybe a`, `(a, b)`, `Identity a` and `Either a b`. If you use+   `foldr` or `forM_` or similar for something like `Maybe a` you should replace+   usages of such function with monomorhpic alternatives:+   * `Maybe`+     + `(?:)          :: Maybe a -> a -> a`+     + `fromMaybe     :: a -> Maybe a -> a`+     + `maybeToList   :: Maybe a -> [a]`+     + `maybeToMonoid :: Monoid m => Maybe m -> m`+     + `maybe         :: b -> (a -> b) -> Maybe a -> b`+     + `whenJust      :: Applicative f => Maybe a -> (a -> f ()) -> f ()`+     + `whenJustM     :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()`++   * `Either`+     + `fromLeft   :: a -> Either a b -> a`+     + `fromRight  :: b -> Either a b -> b`+     + `either     :: (a -> c) -> (b -> c) -> Either a b -> c`+     + `whenRight  :: Applicative f => Either l r -> (r -> f ()) -> f ()`+     + `whenRightM :: Monad m => m (Either l r) -> (r -> m ()) -> m ()`++6. If you have types like `foo :: Foldable f => f a -> a -> a` you should chose one of the following:+   + `Right`: Modify types for `Container` like `foo :: (Container t, Element t ~ a) => t -> a -> a`.+   + `Left`: Import `Data.Foldable` module `qualified` and use everything `Foldable`-related qualified.+7. Forget about `String` type.+   + Replace `putStr` and `putStrLn` with `putText` and `putTextLn`.+   + Replace `(++)` with `(<>)` for `String`-like types.+   + Try to use [`fmt`](http://hackage.haskell.org/package/fmt) library if you need to construct messages.+   + Use `toText/toLText/toString` functions to convert to `Text/LazyText/String` types.+   + Use `encodeUtf8/decodeUtf8` to convert to/from `ByteString`.+8. Run `hlint` using `.hlint.yaml` file from `universum` package to cleanup code and imports.++Projects that use Universum [↑](#structure-of-this-tutorial) ---------------------------  - [cardano-report-server](https://github.com/input-output-hk/cardano-report-server)@@ -289,9 +354,3 @@ - [importify](https://github.com/serokell/importify) - [log-warper](https://github.com/serokell/log-warper) - [orgstat](https://github.com/volhovm/orgstat)--License----------Released under the MIT License.-Copyright (c) 2016, Stephen Diehl, 2016-2017, Serokell
benchmark/Main.hs view
@@ -1,26 +1,18 @@-{-# LANGUAGE ExplicitForAll      #-}-{-# LANGUAGE ScopedTypeVariables #-}- module Main where -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 hiding (show) -import Universum.Container (flipfoldl', foldl')-import Universum.Monad (concatMapM)-import Universum.Nub (hashNub, ordNub, sortNub, unstableNub)-import Universum.VarArg ((...))+import Data.List (nub, zip5)+import Gauge (Benchmark, bench, bgroup, nf, whnf)+import Gauge.Main (defaultMain)+import Prelude (show)  import qualified Data.Foldable as Foldable (elem) import qualified Data.HashSet as HashSet (fromList, insert)-import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.List.NonEmpty as NonEmpty (group, head) import qualified Data.Set as Set (fromList)-import qualified Data.Text as T import qualified Universum.Container as Container (elem)+import qualified Universum.Unsafe as Unsafe  main :: IO () main = defaultMain@@ -76,7 +68,7 @@       ]    groupSort :: [a] -> [a]-  groupSort = map head . group . sort+  groupSort = map Unsafe.head . group . sort    safeSort :: [a] -> [a]   safeSort = map NonEmpty.head . NonEmpty.group . sort@@ -91,7 +83,7 @@ allStrings ch =  [ c : s | s <- "" : allStrings ch, c <- ['a'..ch] ]  nStrings :: Char -> Int -> [Text]-nStrings ch n = take n $ map T.pack $ allStrings ch+nStrings ch n = take n $ map toText $ allStrings ch  bgroupSuperComposition :: Benchmark bgroupSuperComposition = bgroup "(...)"@@ -115,14 +107,14 @@   ]  where   super10 = null-        ... (: []) ... head ... pure ... head-        ... (: [(), (), (), ()]) ... head ... (: []) ... head-        ... (: [()]) ... head ... (: [(), ()]) ... head+        ... (: []) ... Unsafe.head ... pure ... Unsafe.head+        ... (: [(), (), (), ()]) ... Unsafe.head ... (: []) ... Unsafe.head+        ... (: [()]) ... Unsafe.head ... (: [(), ()]) ... Unsafe.head    norm10 = null-         . (: []) . head . pure . head-         . (: [(), (), (), ()]) . head . (: []) . head-         . (: [()]) . head . (: [(), ()]) . head+         . (: []) . Unsafe.head . pure . Unsafe.head+         . (: [(), (), (), ()]) . Unsafe.head . (: []) . Unsafe.head+         . (: [()]) . Unsafe.head . (: [(), ()]) . Unsafe.head    super5arg :: [()] -> [()] -> [()] -> [()] -> [()] -> Bool   super5arg = super10 ... map fst5 ... zip5
src/Universum.hs view
@@ -1,14 +1,62 @@ {-# 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 \#-}------     import Universum--- @+{- | Main module that reexports all functionality allowed to use+without importing any other modules. Just add next lines to your+module to replace default 'Prelude' with better one.++@+\{\-\# LANGUAGE NoImplicitPrelude \#\-\}++__import__ "Universum"+@++This documentation section contains description of internal module structure to+help navigate between modules, search for interesting functionalities and+understand where you need to put your new changes.++Functions and types are distributed across multiple modules and grouped by+meaning or __theme__. Name of the module should give you hints regarding what+this module contains. Some /themes/ contain a great amount of both reexported+functions and functions of our own. To make it easier to understand these huge+chunks of functions, all reexported stuff is moved into separate module with+name @Universum.SomeTheme.Reexport@ and our own functions and types are in+@Universum.SomeTheme.SomeName@. For example, see modules+"Universum.Container.Class" and "Universum.Container.Reexport".++Below is a short description of what you can find under different modules:++* __"Universum.Applicative"__: reexports from "Control.Applicative" and some+  general-purpose applicative combinators.+* __"Universum.Base"__: different general types and type classes from @base@+  package ('Int', 'Num', 'Generic', etc.) not exported by other modules.+* __"Universum.Bool"__: 'Bool' data type with different predicates and combinators.+* __"Universum.Container"__: 'Foldable' replacement, types from @containers@+   and @unordered-containers@ and @vector@ packages.+* __"Universum.Debug"__: @trace@-like debugging functions with compile-time+  warnings (so you don't forget to remove them)+* __"Universum.DeepSeq"__: reexports from "Control.DeepSeq" module and+  functions to evaluate expressions to weak-head normal form or normal form.+* __"Universum.Exception"__: reexports "Control.Exception.Safe" from+  @safe-exceptions@ package, 'bug' as better 'error', 'Exc' pattern synonym for+  convenient pattern-matching on exceptions.+* __"Universum.Function"__: almost everything from "Data.Function" module.+* __"Universum.Functor"__: reexports from "Data.Functor", "Data.Bifunctor",+  other useful 'Functor' combinators.+* __"Universum.Lifted"__: lifted to 'MonadIO' functions to work with console,+  files, 'IORef's, 'MVar's, etc.+* __"Universum.List"__: big chunk of "Data.List", 'NonEmpty' type and+  functions for this type ('head', 'tail', 'last', 'init').+* __"Universum.Monad"__: monad transormers, combinators for 'Maybe' and 'Either'.+* __"Universum.Monoid"__: reexports from "Data.Monoid" and "Data.Semigroup".+* __"Universum.Nub"__: better versions of @nub@ function for list.+* __"Universum.Print"__: polymorphic 'putStrLn' function and functions to print 'Text'.+* __"Universum.String"__: reexports from @text@ and @bytestring@ packages with+    conversion functions between different textual types.+* __"Universum.TypeOps"__: convenient and fancy type-level operators.+* __"Universum.Unsafe"__: unsafe functions (produce 'error').+  Not exported by "Universum" module by default.+* __"Universum.VarArg"__: variadic composition operator '...'.+-}  module Universum        ( -- * Reexports from base and from modules in this repo
src/Universum/Bool/Guard.hs view
@@ -1,3 +1,5 @@+-- | This module contains monadic predicates.+ module Universum.Bool.Guard        ( guardM        , ifM
src/Universum/Bool/Reexport.hs view
@@ -1,3 +1,5 @@+-- | This module reexports functions to work with 'Bool' type.+ module Universum.Bool.Reexport        ( module Control.Monad        , module Data.Bool
src/Universum/Container/Class.hs view
@@ -42,7 +42,7 @@        ) where  import Data.Coerce (Coercible, coerce)-import Prelude hiding (all, and, any, elem, foldMap, foldl, foldr, mapM_, notElem, null, or,+import Prelude hiding (all, and, any, elem, foldMap, foldl, foldr, mapM_, notElem, null, or, print,                 product, sequence_, sum)  import Universum.Applicative (Alternative (..), Const, ZipList, pass)@@ -60,7 +60,7 @@  #if ( __GLASGOW_HASKELL__ >= 800 ) import qualified Data.List.NonEmpty as NE-import Universum.Monoid (NonEmpty)+import Universum.List.Reexport (NonEmpty) #endif  import qualified Data.Foldable as Foldable@@ -86,6 +86,9 @@ import qualified Data.Vector.Unboxed as VU  -- $setup+-- >>> import Universum.Base (even)+-- >>> import Universum.Bool (when)+-- >>> import Universum.Print (print, putTextLn) -- >>> import Universum.String (Text) -- >>> import qualified Data.HashMap.Strict as HashMap @@ -604,45 +607,86 @@ product :: (Container t, Num (Element t)) => t -> Element t product = foldl' (*) 1 --- | Constrained to 'Container' version of 'Data.Foldable.traverse_'.+{- | Constrained to 'Container' version of 'Data.Foldable.traverse_'.++>>> traverse_ putTextLn ["foo", "bar"]+foo+bar++-} traverse_     :: (Container t, Applicative f)     => (Element t -> f b) -> t -> f () traverse_ f = foldr ((*>) . f) pass --- | Constrained to 'Container' version of 'Data.Foldable.for_'.+{- | Constrained to 'Container' version of 'Data.Foldable.for_'.++>>> for_ [1 .. 5 :: Int] $ \i -> when (even i) (print i)+2+4++-} for_     :: (Container t, Applicative f)     => t -> (Element t -> f b) -> f () for_ = flip traverse_ {-# INLINE for_ #-} --- | Constrained to 'Container' version of 'Data.Foldable.mapM_'.+{- | Constrained to 'Container' version of 'Data.Foldable.mapM_'.++>>> mapM_ print [True, False]+True+False++-} mapM_     :: (Container t, Monad m)     => (Element t -> m b) -> t -> m () mapM_ f= foldr ((>>) . f) pass --- | Constrained to 'Container' version of 'Data.Foldable.forM_'.+{- | Constrained to 'Container' version of 'Data.Foldable.forM_'.++>>> forM_ [True, False] print+True+False++-} forM_     :: (Container t, Monad m)     => t -> (Element t -> m b) -> m () forM_ = flip mapM_ {-# INLINE forM_ #-} --- | Constrained to 'Container' version of 'Data.Foldable.sequenceA_'.+{- | Constrained to 'Container' version of 'Data.Foldable.sequenceA_'.++>>> sequenceA_ [putTextLn "foo", print True]+foo+True++-} sequenceA_     :: (Container t, Applicative f, Element t ~ f a)     => t -> f () sequenceA_ = foldr (*>) pass --- | Constrained to 'Container' version of 'Data.Foldable.sequence_'.+{- | Constrained to 'Container' version of 'Data.Foldable.sequence_'.++>>> sequence_ [putTextLn "foo", print True]+foo+True++-} sequence_     :: (Container t, Monad m, Element t ~ m a)     => t -> m () sequence_ = foldr (>>) pass --- | Constrained to 'Container' version of 'Data.Foldable.asum'.+{- | Constrained to 'Container' version of 'Data.Foldable.asum'.++>>> asum [Nothing, Just [False, True], Nothing, Just [True]]+Just [False,True]++-} asum     :: (Container t, Alternative f, Element t ~ f a)     => t -> f a
src/Universum/Debug.hs view
@@ -5,6 +5,9 @@ {-# LANGUAGE PolyKinds          #-} {-# LANGUAGE RankNTypes         #-} {-# LANGUAGE Trustworthy        #-}+#if ( __GLASGOW_HASKELL__ >= 804 )+{-# LANGUAGE TypeInType         #-}+#endif  -- | Functions for debugging. If you left these functions in your code -- then warning is generated to remind you about left usages. Also some
src/Universum/DeepSeq.hs view
@@ -1,3 +1,7 @@+-- | This module contains useful functions to evaluate expressions to weak-head+-- normal form or just normal form. Useful to force traces or @error@ inside+-- monadic computation or to remove space leaks.+ module Universum.DeepSeq        ( module Control.DeepSeq        , evaluateNF
src/Universum/Function.hs view
@@ -1,3 +1,5 @@+-- | This module reexports very basic and primitive functions and function combinators.+ module Universum.Function        ( module Data.Function        , identity
src/Universum/Functor/Fmap.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE Safe #-} +-- | This module contains useful functions to work with 'Functor' type class.+ module Universum.Functor.Fmap        ( map        , (<<$>>)@@ -8,7 +10,21 @@ import Universum.Function ((.)) import Universum.Functor.Reexport (Functor (..)) --- | 'Prelude.map' generalized to 'Functor'.+-- $setup+-- >>> import Universum.Base (negate)+-- >>> import Universum.Bool (Bool (..), not)+-- >>> import Universum.Lifted (getLine)+-- >>> import Universum.Monad (Maybe (..))+-- >>> import Universum.String (toString)++{- | 'Prelude.map' generalized to 'Functor'.++>>> map not (Just True)+Just False+>>> map not [True,False,True,True]+[False,True,False,False]++-} map :: Functor f => (a -> b) -> f a -> f b map = fmap 
src/Universum/Functor/Reexport.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE Safe #-} +-- | This module reexports functionality regarding 'Functor' type class.+ module Universum.Functor.Reexport        ( module Control.Arrow        , module Data.Bifunctor
src/Universum/Lifted/ST.hs view
@@ -1,3 +1,5 @@+-- | This module contains lifted version of 'XIO.stToIO' function.+ module Universum.Lifted.ST        ( stToIO        ) where
src/Universum/List/Reexport.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE CPP         #-} {-# LANGUAGE Trustworthy #-} +-- | This module reexports functinons to work with list, 'NonEmpty' and String types.+ module Universum.List.Reexport        ( module Data.List @@ -18,7 +20,7 @@                   transpose, unfoldr, unzip, unzip3, zip, zip3, zipWith, (++))  #if ( __GLASGOW_HASKELL__ >= 800 )-import Data.List.NonEmpty (head, init, last, tail)+import Data.List.NonEmpty (NonEmpty (..), head, init, last, nonEmpty, tail) #endif  import GHC.Exts (sortWith)
src/Universum/List/Safe.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE CPP         #-} {-# LANGUAGE Trustworthy #-} +-- | This module contains safe functions to work with list type (mostly with 'NonEmpty').+ module Universum.List.Safe        ( list        , uncons@@ -12,8 +14,8 @@  #if ( __GLASGOW_HASKELL__ >= 800 ) import Universum.Applicative (Applicative, pass)+import Universum.List.Reexport (NonEmpty (..)) import Universum.Monad (Monad (..))-import Universum.Monoid (NonEmpty (..)) #endif  import Universum.Functor (fmap)@@ -22,9 +24,10 @@ -- $setup -- >>> import Universum.Applicative (pure) -- >>> import Universum.Base ((==), even)--- >>> import Universum.Bool (Bool (..))+-- >>> import Universum.Bool (Bool (..), not) -- >>> import Universum.Container (length) -- >>> import Universum.Function (($))+-- >>> import Universum.Print (print)  -- | Returns default list if given list is empty. -- Otherwise applies given function to every element.@@ -51,7 +54,13 @@ uncons (x:xs) = Just (x, xs)  #if ( __GLASGOW_HASKELL__ >= 800 )--- | Performs given action over 'NonEmpty' list if given list is non empty.+{- | Performs given action over 'NonEmpty' list if given list is non empty.++>>> whenNotNull [] $ \(b :| _) -> print (not b)+>>> whenNotNull [False,True] $ \(b :| _) -> print (not b)+True++-} whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f () whenNotNull []     _ = pass whenNotNull (x:xs) f = f (x :| xs)
src/Universum/Monad/Container.hs view
@@ -1,5 +1,8 @@ {-# LANGUAGE TypeFamilies #-} +-- | This module exports functions which allow to process instances of+-- 'Container' type class in monadic way.+ module Universum.Monad.Container        ( concatMapM        , concatForM
src/Universum/Monad/Maybe.hs view
@@ -17,9 +17,9 @@ import Universum.Monad.Reexport (Maybe (..), Monad (..))  -- $setup--- >>> import Universum.Bool (Bool (..))+-- >>> import Universum.Bool (Bool (..), not) -- >>> import Universum.Function (($))--- >>> import Universum.Print (putTextLn)+-- >>> import Universum.Print (putTextLn, print) -- >>> import Universum.String (readMaybe)  {- | Similar to 'fromMaybe' but with flipped arguments.@@ -36,9 +36,15 @@ mA ?: b = fromMaybe b mA {-# INLINE (?:) #-} --- | 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>.+{- | 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 Nothing $ \b -> print (not b)+>>> whenJust (Just True) $ \b -> print (not b)+False++-} whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f () whenJust (Just x) f = f x whenJust Nothing _  = pass
src/Universum/Monad/Reexport.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE CPP         #-} {-# LANGUAGE Trustworthy #-} +-- | This module reexports functions to work with monads.+ module Universum.Monad.Reexport        ( -- * Reexport transformers          module Control.Monad.Except
src/Universum/Monoid.hs view
@@ -1,13 +1,11 @@ {-# LANGUAGE CPP #-} +-- | This module reexports functions to work with monoids plus adds extra useful functions.+ module Universum.Monoid-       (+       ( module Data.Monoid #if ( __GLASGOW_HASKELL__ >= 800 )-         module Data.List.NonEmpty-       , module Data.Monoid        , module Data.Semigroup-#else-         module Data.Monoid #endif        , maybeToMonoid        ) where@@ -16,9 +14,8 @@                     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)+                       mtimesDefault, stimesIdempotent, stimesIdempotentMonoid, stimesMonoid) #endif  import Universum.Monad.Reexport (Maybe, fromMaybe)
src/Universum/Nub.hs view
@@ -32,10 +32,26 @@ import Data.Hashable (Hashable) import Data.HashSet as HashSet import Data.Ord (Ord)-import Prelude ((.))+import Data.Set (Set)+import Prelude (Bool, Char, (.))  import qualified Data.Set as Set +-- Liquid Haskell check for duplicates.+{-@ type ListUnique a = {v : [a] | NoDups v} @-}++{-@ predicate NoDups L = Set_emp (dups L) @-}++{-@ measure dups :: [a] -> (Set a)+    dups ([])   = {v | Set_emp v}+    dups (x:xs) = {v | v =+      if (Set_mem x (listElts xs))+      then (Set_cup (Set_sng x) (dups xs))+      else (dups xs)}+@-}++{-@ Set.toList :: Set a -> ListUnique a @-}+ -- | Like 'Prelude.nub' but runs in @O(n * log n)@ time and requires 'Ord'. -- -- >>> ordNub [3, 3, 3, 2, 2, -1, 1]@@ -66,6 +82,7 @@ -- -- >>> sortNub [3, 3, 3, 2, 2, -1, 1] -- [-1,1,2,3]+{-@ sortNub :: [a] -> ListUnique a @-} sortNub :: (Ord a) => [a] -> [a] sortNub = Set.toList . Set.fromList 
src/Universum/String/Conversion.hs view
@@ -4,6 +4,12 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeSynonymInstances  #-} +-- | This module implements type class which allow to have conversion to and+-- from 'Text', 'String' and 'ByteString' types (including both strict and lazy+-- versions). Usually you need to export 'Text' modules qualified and use+-- 'T.pack' \/ 'T.unpack' functions to convert to\/from 'Text'. Now you can+-- just use 'toText' \/ 'toString' functions.+ module Universum.String.Conversion        ( -- * Convenient type aliases          LText
src/Universum/String/Reexport.hs view
@@ -1,3 +1,5 @@+-- | This module reexports functions to work with 'Text' and 'ByteString' types.+ module Universum.String.Reexport        ( -- * String          module Data.String
src/Universum/Unsafe.hs view
@@ -28,8 +28,11 @@ import Data.Maybe (fromJust)  import Universum.Base (Int)-import Universum.Function (flip) +-- Non empty list definition for @liquidhaskell@.+{-@ type NonEmptyList a = {xs : [a] | len xs > 0} @-}+ -- | Similar to '!!' but with flipped arguments.+{-@ at :: n : Nat -> {xs : NonEmptyList a | len xs > n} -> a @-} at :: Int -> [a] -> a-at = flip (!!)+at n xs = xs !! n
src/Universum/VarArg.hs view
@@ -17,6 +17,7 @@ -- >>> import Prelude (show) -- >>> import Data.List (zip5) +-- | This type class allows to implement variadic composition operator. class SuperComposition a b c | a b -> c where     -- | Allows to apply function to result of another function with multiple     -- arguments.
universum.cabal view
@@ -1,5 +1,5 @@ name: universum-version: 1.1.0+version: 1.1.1 cabal-version: >=1.18 build-type: Simple license: MIT@@ -16,6 +16,7 @@ author: Stephen Diehl, @serokell tested-with: GHC ==7.10.3 GHC ==8.0.2 GHC ==8.2.2 extra-doc-files: CHANGES.md+                 CONTRIBUTING.md                  README.md  source-repository head@@ -117,19 +118,19 @@     ghc-options: -threaded  benchmark  universum-benchmark+    +    if impl(ghc ==7.10.3)+        build-depends:+            semigroups >=0.18     type: exitcode-stdio-1.0     main-is: Main.hs     build-depends:         base >=4.9.1.0 && <5,         universum -any,         containers >=0.5.7.1,-        criterion >=1.1.4.0,-        deepseq >=1.4.2.0,-        hashable >=1.2.6.1,-        mtl >=2.2.1,-        semigroups >=0.18.3,-        text >=1.2.2.2,+        gauge >=0.1.3,         unordered-containers >=0.2.8.0     default-language: Haskell2010+    default-extensions: NoImplicitPrelude ScopedTypeVariables     hs-source-dirs: benchmark-    ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N+    ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N