packages feed

universum 1.0.0 → 1.0.1

raw patch · 6 files changed

+331/−14 lines, 6 filesdep ~basedep ~bytestringdep ~containers

Dependency ranges changed: base, bytestring, containers, criterion, deepseq, ghc-prim

Files

CHANGES.md view
@@ -1,3 +1,9 @@+1.0.1+=====++* [#100](https://github.com/serokell/universum/issues/100):+  Add `bug` function = `impureThrow`.+ 1.0.0 ===== 
+ README.md view
@@ -0,0 +1,285 @@+Universum+=========++[![Build Status](https://travis-ci.org/serokell/universum.svg?branch=master)](https://travis-ci.org/serokell/universum)+[![Hackage](https://img.shields.io/hackage/v/universum.svg)](https://hackage.haskell.org/package/universum)+[![Stackage LTS](http://stackage.org/package/universum/badge/lts)](http://stackage.org/lts/package/universum)+[![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.++What is this?+-------------++This README contains introduction to `Universum` and a tutorial on how to use it.++Structure of this tutorial+--------------------------++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.++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+[_Haddock documentation_](http://hackage.haskell.org/package/universum).++Why another custom Prelude?+---------------------------++### 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+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`+[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+[`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`.++### Main goals++While creating and maintaining a custom prelude, we are pursuing the following goals:++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.+   You can still use some [_unsafe_](https://github.com/serokell/universum/blob/master/src/Unsafe.hs)+   functions 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,+   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.+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,+   are used in almost every non-trivial project, and it's really tedious to import them+   manually every time.++Unlike `protolude`, we are:++1. Not trying to be as general as possible (thus we don't export much from+   [`GHC.Generics`](https://github.com/sdiehl/protolude/blob/41710698eedc66fb0bfc5623d3c3a672421fbab5/src/Protolude.hs#L365)).+2. Not trying to maintain every version of `ghc` compiler (only the+   [latest 3](https://github.com/serokell/universum/blob/b6353285859e9ed3544bddbf55d70237330ad64a/.travis.yml#L15)+3. Trying to make writing production code easier (see+   [enhancements and fixes](https://github.com/serokell/universum/issues)).++How to use Universum+----------++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.++Disable the built-in prelude at the top of your file:++```haskell+{-# LANGUAGE NoImplicitPrelude #-}+```++Or directly in your project `.cabal` file, if you want to use in every module by default:++```haskell+default-extensions: NoImplicitPrelude+```++Then add the following import to your modules:++```haskell+import Universum+```++If you're using [Emacs](https://www.gnu.org/software/emacs/), 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.+++Gotchas+-------++* `id` is renamed to `identity` (because it's nice to be able to use `id` as a variable name).+* `head`, `tail`, `last`, `init` work with `NonEmpty a` instead of `[a]`.+* Safe analogue for `head` function: `safeHead :: [a] -> Maybe a`.+* `undefined` triggers a compiler warning, which is probably not what you want. Either use `throwIO`, `Except`, or `error`.+* `map` is `fmap` now.+* `sortOn` is available without import. This function efficiently sorts a list based on some+  property of its elements (e.g. `sortOn length` would sort elements by length).+* Functions `sum` and `product` are strict now, which makes them more efficient.+* If you try to do something like `putStrLn "hi"`, you'll get an error message if+  `OverloadedStrings` is enabled – it happens because the compiler doesn't know what+  type to infer for the string. Use `putText` in this case.+* Since `show` doesn't come from `Show` anymore, you can't write `Show` instances easily.+  Either use autoderived instances or+  [`Buildable`](https://github.com/serokell/universum/blob/f2ccf8afd862e37ccd204c0ef9efde48a05c2d29/src/Universum.hs#L144).+* You can't call some `Foldable` methods over `Maybe` and some other types.+  `Foldable` generalization is useful but+  [potentially error-prone](https://www.reddit.com/r/haskell/comments/60r9hu/proposal_suggest_explicit_type_application_for/).+  Instead we created our own fully compatible with `Foldable`+  [`Container` type class](https://github.com/serokell/universum/blob/b6353285859e9ed3544bddbf55d70237330ad64a/src/Universum/Container/Class.hs#L180)+  but that restricts the usage of functions like `length` over `Maybe`, `Either`, `Identity` and tuples.+  We're also using _GHC 8_ feature of+  [custom compile-time errors](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#custom-compile-time-errors)+  to produce+  [more helpful messages](https://github.com/serokell/universum/blob/54a742c10720f11c739f2d268365d723924b83a9/src/Containers.hs#L474).+* As a consequence of previous point, some functions like `traverse_`, `forM_`, `sequenceA_`, etc.+  are generalized over `Container` type classes.+* `error` takes `Text`.+++Things that you were already using, but now you don't have to import them explicitly+--------------------------------------------------------------------------++### Commonly used libraries++First of all, we reexport some generally useful modules: `Control.Applicative`,+`Data.Traversable`, `Data.Monoid`, `Control.DeepSeq`, `Data.List`, and lots of others.+Just remove unneeded imports after importing `Universum` (GHC should tell you which ones).++Then, some commonly used types: `Map/HashMap/IntMap`, `Set/HashSet/IntSet`, `Seq`, `Text` and `ByteString`+(as well as synonyms `LText` and `LByteString` for lazy versions).++`liftIO` and `MonadIO` are exported by default. A lot of functions are generalized to `MonadIO`.++`deepseq` is exported. For instance, if you want to force deep evaluation of some value (in IO),+you can write `evaluateNF a`. WHNF evaluation is possible with `evaluateWHNF a`.++We also reexport big chunks of these libraries: `mtl`, `stm`, `microlens`, `microlens-mtl`.++[`Bifunctor`](http://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Bifunctor.html)+type class with useful instances is exported.++* `first` and `second` functions apply a function to first/second part of a tuple (for tuples).+* `bimap` takes two functions and applies them to first and second parts respectively.++### Text++We export `Text` and `LText`, and some functions work with `Text` instead of `String` –+specifically, IO functions (`readFile`, `putStrLn`, etc) and `show`. In fact, `show`+is polymorphic and can produce strict or lazy `Text`, `String`, or `ByteString`.+Also, `toS` can convert any string type to any string type, but you can use `toText`, `toByteString`, `toString` functions to convert to any specific type.++### Debugging and `undefined`s++`trace`, `traceM`, `traceShow`, etc. are available by default. GHC will warn you+if you accidentally leave them in code, however (same for `undefined`).++We also have `data Undefined = Undefined` (which, too, comes with warnings).++### Exceptions++We use [`safe-exceptions`](https://github.com/fpco/safe-exceptions)+library for exceptions handling. Don't import `Control.Exceptions`+module explicitly. Instead use functionality from `safe-exceptions`+provided by `universum` or import `Control.Exceptions.Safe` module.++What's new?+-----------++Finally, we can move to part describing the new cool features we bring with `universum`.++* `uncons` splits a list at the first element.+* `ordNub` and `sortNub` are _O(n log n)_ versions of `nub` (which is quadratic)+  and `hashNub` and `unstableNub` are almost _O(n)_ versions of `nub`.+* `(&)` – reverse application. `x & f & g` instead of `g $ f $ x` is useful sometimes.+* `pretty` and `prettyL` for converting `Buildable` into `Text` (can be used instead of `show`).+* `whenM`, `unlessM`, `ifM`, `guardM` are available and do what you expect+  them to do (e.g. `whenM (doesFileExist "foo")`).+* Very generalized version of `concatMapM`, too, is available and does what expected.+* `readMaybe` and `readEither` are like `read` but total and give either+  `Maybe` or `Either` with parse error.+* `when(Just|Nothing|Left|Right|NotEmpty)[M][_]`+  let you conditionally execute something. Before:++  ```haskell+  case mbX of+      Nothing -> return ()+      Just x  -> ... x ...+  ```++  After:++  ```haskell+  whenJust mbX $ \x ->+      ... x ...+  ```++* `for_` for loops. There's also `forM_` but `for_` looks a bit nicer.++  ```haskell+  for_ [1..10] $ \i -> do+      ...+  ```++* `andM`, `allM`, `anyM`, `orM` are monadic version of corresponding functions from `base`.+* Type operator `$` for writing types like `Maybe $ Either String $ Maybe Int`.+* `Each` type family. So this:++  ```haskell+  f :: Each [Show, Read] [a, b] => a -> b -> String+  ```++  translates into this:++  ```haskell+  f :: (Show a, Show b, Read a, Read b) => a -> b -> String+  ```++* `With` type operator. So this:++  ```haskell+  a :: With [Show, Read] a => a -> a+  ```++  translates into this:++  ```haskell+  a :: (Show a, Read a) => a -> a+  ```++* Variadic composition operator `(...)`. So you can write:++  ```haskell+  ghci> (show ... (+)) 1 2+  "3"+  ghci> show ... 5+  "5"+  ghci> (null ... zip5) [1] [2] [3] [] [5]+  True+  ghci> let process = map (+3) ... filter+  ghci> process even [1..5]+  [5,7]+  ```++* Conversions between `Either` and `Maybe` like `rightToMaybe` and `maybeToLeft`+  with clear semantic.+* `using(Reader|State)[T]` functions as aliases for `flip run(Reader|State)[T]`.+* [`One` type class](https://github.com/serokell/universum/blob/master/src/Containers.hs#L473)+  for creating singleton containers. Even monomorhpic ones like `Text`.+* `evaluateWHNF` and `evaluateNF` functions as clearer and lifted aliases for+  `evaluate` and `evaluate . force`.++License+-------++Released under the MIT License.+Copyright (c) 2016, Stephen Diehl, 2016-2017, Serokell
src/Universum/Base.hs view
@@ -74,7 +74,7 @@ import Data.Void (Void, absurd, vacuous) #endif -import GHC.Base (String, asTypeOf, maxInt, minInt, ord, seq, (++))+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 (..))
src/Universum/Exception.hs view
@@ -7,6 +7,10 @@  module Universum.Exception        ( module Control.Exception.Safe+#if ( __GLASGOW_HASKELL__ >= 800 )+       , Bug (..)+       , bug+#endif        , note        ) where @@ -18,6 +22,28 @@ 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 (displayException, 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) = Safe.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.
src/Universum/List/Reexport.hs view
@@ -15,7 +15,7 @@                   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)+                  transpose, unfoldr, unzip, unzip3, zip, zip3, zipWith, (++))  #if ( __GLASGOW_HASKELL__ >= 800 ) import Data.List.NonEmpty (head, init, last, tail)
universum.cabal view
@@ -1,6 +1,6 @@ name: universum-version: 1.0.0-cabal-version: >=1.10+version: 1.0.1+cabal-version: >=1.18 build-type: Simple license: MIT license-file: LICENSE@@ -15,8 +15,8 @@ category: Prelude author: Stephen Diehl, @serokell tested-with: GHC ==7.10.3 GHC ==8.0.1 GHC ==8.0.2 GHC ==8.2.2-extra-source-files:-    CHANGES.md+extra-doc-files: CHANGES.md+                 README.md  source-repository head     type: git@@ -65,10 +65,10 @@         Universum.VarArg     build-depends:         base >=4.8 && <5,-        bytestring >=0.10.8.1,-        containers >=0.5.7.1,-        deepseq >=1.4.2.0,-        ghc-prim >=0.5.0.0,+        bytestring >=0.10.8.2,+        containers >=0.5.10.2,+        deepseq >=1.4.3.0,+        ghc-prim >=0.5.1.1,         hashable >=1.2.6.1,         microlens >=0.4.8.1,         microlens-mtl >=0.1.11.0,@@ -92,11 +92,11 @@     type: exitcode-stdio-1.0     main-is: Main.hs     build-depends:-        base >=4.9.1.0 && <5,+        base >=4.10.1.0 && <5,         universum -any,-        containers >=0.5.7.1,-        criterion >=1.1.4.0,-        deepseq >=1.4.2.0,+        containers >=0.5.10.2,+        criterion >=1.2.6.0,+        deepseq >=1.4.3.0,         hashable >=1.2.6.1,         mtl >=2.2.1,         semigroups >=0.18.3,