packages feed

relude 0.4.0 → 0.5.0

raw patch · 60 files changed

+940/−255 lines, 60 filesdep +QuickCheck

Dependencies added: QuickCheck

Files

CHANGELOG.md view
@@ -1,11 +1,37 @@-# Change log+# Changelog -Unreleased-====+`relude` uses [PVP Versioning][1].+The changelog is available [on GitHub][2]. -0.4.0 — Nov 6, 2018-=====+## 0.5.0 — Mar 18, 2019 +* [#127](https://github.com/kowainik/relude/issues/127):+  Implement `Relude.Extra.Lens` module.+* [#125](https://github.com/kowainik/relude/issues/125):+  Moved many numerical functions and types in `Relude.Numeric`.+  Reexport `toIntegralSized` from `Data.Bits`.+  Add `integerToBounded` and `integerToNatural` in `Relude.Numeric`.+* [#121](https://github.com/kowainik/relude/issues/121):+  Reexport `Ap` from `Data.Monoid`. Change definition of `foldMapA` to use `Ap`.+* [#129](https://github.com/kowainik/relude/issues/129):+  Add `appliedTo` and `chainedTo` as named versions of operators `=<<` and `<**>`.+* [#138](https://github.com/kowainik/relude/issues/138):+  Add `RealFloat` to `Relude.Numeric`.+* [#144](https://github.com/kowainik/relude/issues/144):+  Add `traverseToSnd` and friends to `Relude.Extra.Tuple`.+* [#140](https://github.com/kowainik/relude/issues/140):+  Improve text of custom compile-time error messages for `elem` functions.+* [#136](https://github.com/kowainik/relude/issues/136):+  Cover `Relude.Extra.*` modules with custom HLint rules.+* [#146](https://github.com/kowainik/relude/issues/146):+  Improve documentation for `Relude.File` file: be more explicit about system+  locale issues.+* Improve documentation for `One` typeclass and add tests.+* Support ghc-8.6.4 and ghc-8.4.4.+  Drop support for ghc-8.6.1 and ghc-8.4.3.++## 0.4.0 — Nov 6, 2018+ * [#70](https://github.com/kowainik/relude/issues/70):   Reexport `Contravariant` for GHC >= 8.6.1. * [#103](https://github.com/kowainik/relude/pull/104):@@ -35,8 +61,7 @@ * [#109](https://github.com/kowainik/relude/issues/109):   Use Dhall v3.0.0 for hlint file generation. -0.3.0-=====+## 0.3.0  * [#41](https://github.com/kowainik/relude/issues/41):   Add `Foldable1`.@@ -71,8 +96,7 @@ * [#60](https://github.com/kowainik/relude/issues/60):   Add `hoistMaybe` and `hoistEither` functions. -0.2.0-=====+## 0.2.0  * [#43](https://github.com/kowainik/relude/issues/43):   Implement `Relude.Extra.Newtype` module.@@ -90,14 +114,12 @@   Remove `safeHead`.   Rename `Relude.List.Safe` to `Relude.List.NonEmpty`. -0.1.1-=====+## 0.1.1  * [#44](https://github.com/kowainik/relude/issues/44):   Implement parser deriviation from pretty-printers. -0.1.0-=====+## 0.1.0  * [#7](https://github.com/kowainik/relude/issues/7):   Remove `Container.Class.Container`. Export `Foldable`.@@ -138,9 +160,6 @@ * [#8](https://github.com/kowainik/relude/issues/8):   Introduce `StaticMap` and `DynamicMap` type classes as universal interface for   Map-like structures.--`relude` uses [PVP Versioning][1].-The change log is available [on GitHub][2].  [1]: https://pvp.haskell.org [2]: https://github.com/kowainik/relude/releases
README.md view
@@ -16,7 +16,7 @@    behavior and usage of such functions can lead to the unexpected bugs. Though    you can still use some unsafe functions from `Relude.Unsafe` module, but they    are not exported by default.-2. **Type-safety**. We like to make invalid states unrepresantable. And if it's+2. **Type-safety**. We like to make invalid states unrepresentable. And if it's    possible to express this concept through the types then we will do it.      _Example:_@@ -56,12 +56,17 @@  This tutorial has several parts: -1. [Get started.](#get-started-)-2. [Difference from `Prelude`.](#difference-from-prelude-)-3. [Reexports.](#reexports-)+1. [Get started](#get-started-)+    * [base-noprelude](#base-noprelude-)+    * [Mixins](#mixins-)+    * [NoImplicitPrelude](#NoImplicitPrelude-)+2. [Difference from Prelude](#difference-from-prelude-)+3. [Reexports](#reexports-) 4. [What's new?](#whats-new-)-6. [Migration guide.](#migration-guide-)-7. [For developers.](#for-developers-)+6. [Migration guide](#migration-guide-)+7. [Comparison with other alternative preludes](#comparison-with-other-alternative-preludes-)+    * [Relude vs Protolude](#relude-vs-protolude-)+8. [For developers](#for-developers-)  This is neither a tutorial on _Haskell_ nor tutorial on each function contained in `Relude`. For detailed documentation of every function together with examples@@ -70,9 +75,9 @@ ## Get started [↑](#structure-of-this-tutorial)  If you want to start using `relude` in your project and explore it with the help-of compiler, set everything up according to the instructions below.+of compiler, set everything up according to one of the instructions below. -### base-noprelude+### base-noprelude [↑](#structure-of-this-tutorial)  This is the recommended way to use custom prelude. It requires you to perform the following steps:@@ -98,21 +103,55 @@ you don't need to import module manually inside each file and enable the `NoImplicitPrelude` extension. -### Per-file configuration+### Mixins [↑](#structure-of-this-tutorial) +You can use Cabal feature `mixins` to replace the default `Prelude` with `Relude`+without need to add extra dependencies or import `Relude` manually each time.+See the following example:++> **NOTE:** this requires Cabal version to be at least `2.2`++```cabal+cabal-version:       2.2+name:                prelude-example+version:             0.0.0.0++library+  exposed-modules:     Example+  build-depends:       base >= 4.10 && < 4.13+                     , relude ^>= 0.4.0++  mixins:              base hiding (Prelude)+                     , relude (Relude as Prelude)++  default-language:    Haskell2010+```++If you want to be able to import `Extra.*` modules when using `mixins` approach,+you need to list those modules under `mixins` field as well, like this:++```cabal+  mixins:              base hiding (Prelude)+                     , relude (Relude as Prelude, Relude.Extra.Enum)+```++### NoImplicitPrelude [↑](#structure-of-this-tutorial)+ 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:+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:+Add `relude` as a dependency of your project. Then add the following import to+your modules:  ```haskell import Relude@@ -132,8 +171,11 @@     space-efficient). So you should write `sortOn length` (would sort elements     by length) but `sortWith fst` (would sort list of pairs by first element). * Functions `sum` and `product` are strict now, which makes them more efficient.-* Since `show` doesn't come from `Show` anymore, you need to export `Show` from-  `Text.Show` module if you want to implement `Show` instance manually.+* Since `show` doesn't come from `Show` anymore, you need to export+  `Text.Show` module if you want to implement `Show` instance manually. This can be done like this:+  ```haskell+  import qualified Text.Show+  ``` * You can't call `elem` and `notElem` functions over `Set` and `HashSet`. These   functions are forbidden for these two types because of the performance reasons. * `error` takes `Text`.@@ -200,7 +242,7 @@ `Text/LText/String`. If you want to convert to and from `ByteString` use `encodeUtf8/decodeUtf8` functions. -### transforms & mtl+### transformers & mtl  The following parts of these two libraries are exported: @@ -273,7 +315,7 @@ ### Need to import explicitly  * Convenient functions to work with `(Bounded a, Enum a)` types:-  1. `universe :: (Bounded a, Enum a) => [a`: get all values of the type.+  1. `universe :: (Bounded a, Enum a) => [a]`: get all values of the type.   2. `inverseMap :: (Bounded a, Enum a, Ord k) => (a -> k) -> k -> Maybe a`: convert functions like `show` to parsers. * Nice helpers to deal with `newtype`s in a more pleasant way: @@ -303,6 +345,8 @@ In order to replace default `Prelude` with `relude` you should start with instructions given in [_get started_](#get-started-) section. +### Code changes+ This section describes what you need to change to make your code compile with `relude`.  1. Enable `-XOverloadedStrings` extension by default for your project.@@ -335,11 +379,76 @@  5. Forget about `String` type.    + 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`.    + Use `(putStr[Ln]|readFile|writeFile|appendFile)[Text|LText|BS|LBS]` functions. 6. Run `hlint` using `.hlint.yaml` file from `relude` package to cleanup code and imports.++### Running HLint on CI++Instead of storing a `relude`-specific `.hlint.yaml` file inside your repository,+you can run HLint with this file automatically on any CI service such as+[Travis CI](https://travis-ci.org/) or [Circle CI](https://circleci.com/).+For this you need to:++1. Find the commit hash of the `relude` version you are using (can be found in [releases](https://github.com/kowainik/relude/releases)).+2. Run the command that downloads `.hlint.yaml` for that version.+3. Run `hlint` using this file.++For the latest `relude` version, this can be achieved by executing the following+two commands on your CI:++```yaml+curl https://raw.githubusercontent.com/kowainik/relude/55968311244690f5cc8b4484a37a63d988ea2ec4/.hlint.yaml -o .hlint-relude.yaml+curl -sSL https://raw.github.com/ndmitchell/neil/master/misc/travis.sh | sh -s -- hlint -h .hlint-relude.yaml .+```++See an example of this feature being used in [Summoner](https://github.com/kowainik/summoner/blob/b6c3ecb7cd9bc8d1451e2cc78cd020cd2e473564/.travis.yml#L58-L59).++## Comparison with other alternative preludes [↑](#structure-of-this-tutorial)++There are quite a few libraries that can be used as alternative preludes in+Haskell, let's compare Relude with some of them.++### Relude vs Protolude [↑](#structure-of-this-tutorial)++[Protolude](https://github.com/sdiehl/protolude) is one of the most popular+alternative preludes. It's also relatively small, but:++1. Protolude supports older GHC versions (from GHC 7.6.1) while `relude` only+   supports from GHC 8.0.2. So if you aim ancient GHC versions, `protolude`+   might be a better choice. But because of that it contains a lot of CPP, code+   is ugly in some places as a consequence and it's more difficult to add,+   remove or change things there.+2. `relude` has much better documentation:+    * [High-level overview of internal module structure](http://hackage.haskell.org/package/relude/docs/Relude.html)+    * 100% Haddock coverage+    * Almost every function has usage examples and all examples are tested with+      `doctest` (which also sometimes hard to do because of multiple GHC+      versions support, but we try really hard)+    * [Tutorial + migration guide](structure-of-this-tutorial) from+      `Prelude` and just general description of the whole package and libraries+      it depends on.+3. `relude` has custom HLint rules specific to it: you can use them to remove+   redundant imports or find hints how to use functions from `relude`. Moreover,+   the HLint rules are generated using Dhall and there is [a blog post about+   this technique](https://kowainik.github.io/posts/2018-09-09-dhall-to-hlint).+   This allows to maintain HLint rules much easier because it's already not an+   easy task.+4. `relude` has less dependencies and is slightly lighter because of that but still+   very powerful and useful.+5. One minor difference: `head` in `protolude` returns `Maybe a` while in+   `relude` it works with `NonEmpty`.+6. Minor feature: `relude` uses type-level magic to forbid `elem` and `notElem`+   functions for `Set` and `HashSet` (because `elem` from `Foldable` run in+   _O(n)_ time and you can accidentally use `elem` from `Foldable` but with+   `relude` you can't).+7. `relude` is opt-in oriented and has a notion of `Extra.*` modules that are+   not exported by default from the `Relude` module. So we don't spoil global+   namespace but still have a lot of useful features like polymorphic functions+   to work with every `newtype`, `Enum/Bounded`-related useful utilities,+   functions to take a name of any type as `Text` and much more. It's very easy+   to make them accessible package-wide with `base-noprelude` trick!  ## For Developers [↑](#structure-of-this-tutorial) 
benchmark/Main.hs view
@@ -1,8 +1,9 @@ {--Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik-License: MIT+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik+License:    MIT+Maintainer: Kowainik <xrom.xkov@gmail.com> -}  module Main where
relude.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.0 name:                relude-version:             0.4.0+version:             0.5.0 synopsis:            Custom prelude from Kowainik description:     == Goals@@ -48,16 +48,16 @@ bug-reports:         https://github.com/kowainik/relude/issues license:             MIT license-file:        LICENSE-author:              Stephen Diehl, @serokell, Kowainik+author:              Kowainik, Stephen Diehl, Serokell maintainer:          Kowainik <xrom.xkov@gmail.com>-copyright:           2016 Stephen Diehl, 2016-2018 Serokell, 2018 Kowainik+copyright:           2016 Stephen Diehl, 2016-2018 Serokell, 2018-2019 Kowainik category:            Prelude stability:           stable build-type:          Simple tested-with:         GHC == 8.0.2                    , GHC == 8.2.2-                   , GHC == 8.4.3-                   , GHC == 8.6.1+                   , GHC == 8.4.4+                   , GHC == 8.6.4 extra-doc-files:     CHANGELOG.md                    , CONTRIBUTING.md                    , README.md@@ -105,17 +105,19 @@                                Relude.Monad.Trans                            Relude.Monoid                            Relude.Nub+                           Relude.Numeric                            Relude.Print                            Relude.String                                Relude.String.Conversion                                Relude.String.Reexport                             -- not exported by default-                           Relude.Extra.Bifunctor                          +                           Relude.Extra.Bifunctor                            Relude.Extra.CallStack                            Relude.Extra.Enum                            Relude.Extra.Foldable1                            Relude.Extra.Group+                           Relude.Extra.Lens                            Relude.Extra.Map                            Relude.Extra.Newtype                            Relude.Extra.Tuple@@ -181,6 +183,7 @@   build-depends:       base >= 4.9 && < 5                      , doctest                      , Glob+                     , QuickCheck    ghc-options:         -threaded   default-language:    Haskell2010
src/Relude.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Trustworthy #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -71,6 +71,7 @@   monad transormers, various combinators. * __"Relude.Monoid"__: reexports from "Data.Monoid" and "Data.Semigroup". * __"Relude.Nub"__: better versions of @nub@ function for list.+* __"Relude.Numeric"__: functions and types to work with numerical data. * __"Relude.Print"__: printing to terminal functions for 'Text' and 'ByteString'. * __"Relude.String"__: reexports from @text@ and @bytestring@ packages with     conversion functions between different textual types.@@ -86,6 +87,8 @@ * __"Relude.Extra.Foldable1"__: 'Foldable1' typeclass like 'Foldable' but for   non-empty structures. * __"Relude.Extra.Group"__: grouping functions, polymorphic on return @Map@ type.+* __"Relude.Extra.Lens"__: minimal implementation of @lens@ package required+for basic usage. * __"Relude.Extra.Map"__: typeclass for @Map@-like data structures. * __"Relude.Extra.Newtype"__: generic functions that automatically work for any   @newtype@.@@ -114,6 +117,7 @@        , module Relude.Monad        , module Relude.Monoid        , module Relude.Nub+       , module Relude.Numeric        , module Relude.Print        , module Relude.String        ) where@@ -134,5 +138,6 @@ import Relude.Monad import Relude.Monoid import Relude.Nub+import Relude.Numeric import Relude.Print import Relude.String
src/Relude/Applicative.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -15,12 +15,14 @@ module Relude.Applicative        ( module Control.Applicative        , pass+       , appliedTo        ) where  import Control.Applicative (Alternative (..), Applicative (..), Const (..), ZipList (..), liftA2,                             liftA3, optional, (<**>))  -- $setup+-- >>> import Relude -- >>> import Relude.Monad (Maybe)  -- | Shorter alias for @pure ()@.@@ -29,6 +31,21 @@ -- Just () pass :: Applicative f => f () pass = pure ()++{- | For chaining applicative operations in forward applications using '(&)'+Named version of the '<**>' operator, which is '<*>' but flipped++>>> Just (+ 1) & appliedTo (Just 2)+Just 3+>>> Just (+) & appliedTo (Just 1) & appliedTo (Just 2)+Just 3+>>> Nothing & appliedTo (Just 2)+Nothing+-}+appliedTo :: Applicative f => f a -> f (a -> b) -> f b+appliedTo = (<**>)+{-# INLINE appliedTo #-}+  {- orAlt :: (Alternative f, Monoid a) => f a -> f a
src/Relude/Base.hs view
@@ -2,9 +2,9 @@ {-# LANGUAGE Unsafe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -14,11 +14,7 @@  module Relude.Base        ( -- * Base types-         module Data.Bits-       , module Data.Char-       , module Data.Int-       , module Data.Word-       , Natural+         module Data.Char           -- * Base type classes        , module Data.Eq@@ -36,12 +32,10 @@         , module GHC.Base        , module GHC.Enum-       , module GHC.Float        , module GHC.Generics-       , module GHC.Num-       , module GHC.Real        , module GHC.Show +-- * GHC-specific functionality #if MIN_VERSION_base(4,10,0)        , module GHC.TypeNats #else@@ -54,11 +48,7 @@        ) where  -- Base types-import Data.Bits (xor) import Data.Char (Char, chr)-import Data.Int (Int, Int16, Int32, Int64, Int8)-import Data.Word (Word, Word16, Word32, Word64, Word8, byteSwap16, byteSwap32, byteSwap64)-import Numeric.Natural (Natural)  -- IO import System.IO (FilePath, Handle, IO, IOMode (..), stderr, stdin, stdout, withFile)@@ -74,13 +64,9 @@ import Data.Typeable (Typeable) import Data.Void (Void, absurd, vacuous) -import GHC.Base (String, asTypeOf, maxInt, minInt, ord, seq, ($!))+import GHC.Base (String, asTypeOf, ord, seq, ($!)) import GHC.Enum (Bounded (..), Enum (..), boundedEnumFrom, boundedEnumFromThen)-import GHC.Float (Double (..), Float (..), Floating (acos, acosh, asin, asinh, atan, atanh, cos, cosh, exp, logBase, pi, sin, sinh, sqrt, tan, tanh, (**))) import GHC.Generics (Generic)-import GHC.Num (Integer, Num (..), subtract)-import GHC.Real (Fractional (..), Integral (..), Ratio, Rational, Real (..), RealFrac (..),-                 denominator, even, fromIntegral, gcd, lcm, numerator, odd, realToFrac, (^), (^^)) import GHC.Show (Show)  #if MIN_VERSION_base(4,10,0)
src/Relude/Bool.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Bool/Guard.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -19,7 +19,7 @@  import Relude.Bool.Reexport (Bool (..), guard, unless, when) import Relude.Function (flip)-import Relude.Monad (Monad, return, MonadPlus, (>>=))+import Relude.Monad (Monad, MonadPlus, return, (>>=))  -- $setup -- >>> import Relude.Applicative (pure)
src/Relude/Bool/Reexport.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Container.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Container/One.hs view
@@ -3,21 +3,26 @@ {-# LANGUAGE TypeFamilies      #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> -Typeclass for creating structures from singleton element.+Typeclass for creating structures from a singleton element. It has three main goals:++1. Give a shorter name for the construction: uses 'one' instead of common @singleton@.+2. Work with monomorphic structures like 'T.Text' or 'IntSet'.+3. Give a clearer and less scary name for cases where you can use 'pure' or @(:[])@. -}  module Relude.Container.One        ( One (..)        ) where -import Relude.Base (Char, Int, Word8)+import Relude.Base (Char) import Relude.Container.Reexport (HashMap, HashSet, Hashable, IntMap, IntSet, Map, Set, uncurry)+import Relude.Numeric (Int, Word8)  import qualified Data.List.NonEmpty as NE @@ -37,10 +42,13 @@ import qualified Data.Set as Set  -- $setup--- >>> import Relude.Base (Int, String)--- >>> import Relude.Bool (Bool (..))--- >>> import Relude.String (Text)+-- >>> import Relude+-- >>> import qualified Data.IntSet as IntSet -- >>> import qualified Data.HashMap.Strict as HashMap+-- >>> import qualified Data.Text as Text+-- >>> import qualified Data.ByteString as ByteString+-- >>> import qualified Data.Text.Lazy as LText+-- >>> import qualified Data.ByteString.Lazy as LByteString  {- | Typeclass for data types that can be created from one element. @@ -50,6 +58,13 @@ "a" >>> one (3, "hello") :: HashMap Int String fromList [(3,"hello")]++__Laws:__++* __@single-size@__: @∀ x . size (one x) ≡ 1@++(where @size@ is a specific function for each container that returns the size of+this container) -} class One x where     -- | Type of single element of the structure.@@ -59,38 +74,89 @@  -- Lists +{- | Allows to create a singleton list. You might prefer function with name 'one'+instead of 'pure' or @(:[])@.++>>> one 42 :: [Int]+[42]++prop> length (one @[Int] x) == 1+-} instance One [a] where     type OneItem [a] = a     one = (:[])     {-# INLINE one #-} +{- | Allows to create singleton 'NE.NonEmpty' list. You might prefer function with+name 'one' instead of 'pure' or @(:|[])@.++>>> one 42 :: NonEmpty Int+42 :| []++prop> length (one @(NonEmpty Int) x) == 1+-} instance One (NE.NonEmpty a) where     type OneItem (NE.NonEmpty a) = a     one = (NE.:|[])     {-# INLINE one #-} +{- | Create singleton 'SEQ.Seq'.++>>> one 42 :: Seq Int+fromList [42]++prop> length (one @(Seq Int) x) == 1+-} instance One (SEQ.Seq a) where     type OneItem (SEQ.Seq a) = a-    one = (SEQ.empty SEQ.|>)+    one = SEQ.singleton     {-# INLINE one #-}  -- Monomorphic sequences +{- | Create singleton strict 'T.Text'.++>>> one 'a' :: Text+"a"++prop> Text.length (one x) == 1+-} instance One T.Text where     type OneItem T.Text = Char     one = T.singleton     {-# INLINE one #-} +{- | Create singleton lazy 'TL.Text'.++>>> one 'a' :: LText+"a"++prop> LText.length (one x) == 1+-} instance One TL.Text where     type OneItem TL.Text = Char     one = TL.singleton     {-# INLINE one #-} +{- | Create singleton strict 'BS.ByteString'.++>>> one 97 :: ByteString+"a"++prop> ByteString.length (one x) == 1+-} instance One BS.ByteString where     type OneItem BS.ByteString = Word8     one = BS.singleton     {-# INLINE one #-} +{- | Create singleton lazy 'BSL.ByteString'.++>>> one 97 :: LByteString+"a"++prop> LByteString.length (one x) == 1+-} instance One BSL.ByteString where     type OneItem BSL.ByteString = Word8     one = BSL.singleton@@ -98,16 +164,37 @@  -- Maps +{- | Create singleton 'Map' from key-value pair.++>>> one (3, "foo") :: Map Int Text+fromList [(3,"foo")]++prop> length (one @(Map Int String) x) == 1+-} instance One (Map k v) where     type OneItem (Map k v) = (k, v)     one = uncurry M.singleton     {-# INLINE one #-} +{- | Create singleton 'HashMap' from key-value pair.++>>> one (3, "foo") :: HashMap Int Text+fromList [(3,"foo")]++prop> length (one @(HashMap Int String) x) == 1+-} instance Hashable k => One (HashMap k v) where     type OneItem (HashMap k v) = (k, v)     one = uncurry HM.singleton     {-# INLINE one #-} +{- | Create singleton 'IntMap' from key-value pair.++>>> one (3, "foo") :: IntMap Text+fromList [(3,"foo")]++prop> length (one @(IntMap String) x) == 1+-} instance One (IntMap v) where     type OneItem (IntMap v) = (Int, v)     one = uncurry IM.singleton@@ -115,16 +202,37 @@  -- Sets +{- | Create singleton 'Set'.++>>> one 42 :: Set Int+fromList [42]++prop> length (one @(Set Int) x) == 1+-} instance One (Set v) where     type OneItem (Set v) = v     one = Set.singleton     {-# INLINE one #-} +{- | Create singleton 'HashSet'.++>>> one 42 :: HashSet Int+fromList [42]++prop> length (one @(HashSet Int) x) == 1+-} instance Hashable v => One (HashSet v) where     type OneItem (HashSet v) = v     one = HashSet.singleton     {-# INLINE one #-} +{- | Create singleton 'IntSet'.++>>> one 42 :: IntSet+fromList [42]++prop> IntSet.size (one x) == 1+-} instance One IntSet where     type OneItem IntSet = Int     one = IS.singleton
src/Relude/Container/Reexport.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Debug.hs view
@@ -11,9 +11,9 @@ #endif  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/DeepSeq.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Exception.hs view
@@ -4,9 +4,9 @@ {-# LANGUAGE ViewPatterns          #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Extra/Bifunctor.hs view
@@ -1,5 +1,5 @@ {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Extra/CallStack.hs view
@@ -1,5 +1,5 @@ {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Extra/Enum.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeApplications    #-}  {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Extra/Foldable1.hs view
@@ -2,8 +2,8 @@ {-# LANGUAGE TypeApplications #-}  {- |-Copyright: (c) 2011-2015 Edward Kmett-           (c) 2018 Kowainik+Copyright:  (c) 2011-2015 Edward Kmett+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> -}
src/Relude/Extra/Group.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeFamilies        #-}  {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
+ src/Relude/Extra/Lens.hs view
@@ -0,0 +1,213 @@+{-# LANGUAGE Rank2Types #-}++{- |+Copyright:  (c) 2013-2016 Edward Kmett+            (c) 2019 Kowainik+License:    MIT+Maintainer: Kowainik <xrom.xkov@gmail.com>++This module aims to provide a minimal implementation of @lens@ package required+for basic usage. All functions are compatible with the real @lens@ package+therefore if you need to expand to the full version the process should be+straightforward.++== Usage++To use lenses in your project, you don't need to add any other dependency rather+than @relude@. You should add the import of this module in the place of lenses+usage:++@+__import__ Relude.Extra.Lens+@++== Example++To understand better how to use this module lets look at some simple example.+Let's say we have the user data type in our system:++@+__data__ User = User+    { userName    :: 'Text'+    , userAge     :: 'Int'+    , userAddress :: Address+    } __deriving__ ('Show')++__data__ Address = Address+    { addressCountry :: 'Text'+    , addressCity    :: 'Text'+    , addressIndex   :: 'Text'+    } __deriving__ ('Show')+@++To create the lens for the @userName@ field we can use 'lens' function and manually writing getter and setter function:++@+nameL :: 'Lens'' User 'Text'+nameL = 'lens' getter setter+  __where__+    getter :: User -> 'Text'+    getter = userName++    setter :: User -> 'Text' -> User+    setter user newName = user {userName = newName}+@++In this manner, we can create other lenses for our User data type.++@+ageL     :: 'Lens'' User 'Int'+addressL :: 'Lens'' User Address+countryL :: 'Lens'' User 'Text'+cityL    :: 'Lens'' User 'Text'+indexL   :: 'Lens'' User 'Text'+@++/Note:/ here we are using composition of the lenses for @userAddress@ field. If we have++@+adressCityL :: 'Lens'' Address 'Text'+@++then++@+cityL = addressL . adressCityL+@++Let's say we have some sample user++@+user :: User+user = User+    { userName = \"John\"+    , userAge  = 42+    , userAddress = Address+        { addressCountry = \"UK\"+        , addressCity    = \"London\"+        , addressIndex   = \"XXX\"+        }+    }+@++To view the fields of the User data type we can use 'view' or '^.'++@+__>>>__ 'view' ageL user+42+__>>>__ user '^.' cityL+\"London\"+@++If we want to change any of the user's data, we should use 'set' or '.~'++@+__>>>__ 'set' nameL \"Johnny\" user+__>>>__ user '&' indexL '.~' \"YYY\"+@++'over' or '%~' operator could be useful when, for example, you want to increase the age by one on the user's birthday:++@+__>>>__ 'over' ageL 'succ' user+__>>>__ user '&' ageL '%~' 'succ'+@++== Migration++This module is not supposed to be the replacement for the @lens@ package. One of+the reasons why one would want to migrate to @lens@ or @microlens@ is that the+functional in @relude@ is limited to just vital lens functions.++To migrate to @lens@ or @microlens@ package add the required library to the+dependencies list in the @.cabal@ file and replace the import from @relude@+library++@+__import__ Relude.Extra.Lens+@++to the one of this correspondingly:++- @lens@:++    @+    __import__ Control.Lens+    @++- @microlens@:++    @+    __import__ Lens.Micro+    @++And that's all! No need to change the types or implementation of the functions+you used @Relude.Extra.Lens@ in.++== Links++- [lens](https://hackage.haskell.org/package/lens)+- [microlens](https://hackage.haskell.org/package/microlens)+- [lens tutorial](http://hackage.haskell.org/package/lens-tutorial-1.0.3/docs/Control-Lens-Tutorial.html)++-}++module Relude.Extra.Lens+       ( Lens'+       , lens+       , view+       , set+       , over+       , (^.)+       , (.~)+       , (%~)+       ) where++import Relude++{- | The monomorphic lenses which don't change the type of the container (or of+the value inside). It has a 'Functor' constraint, and since both 'Const' and+'Identity' are functors, it can be used whenever a getter or a setter is needed.++  * @a@ is the type of the value inside of structure+  * @s@ is the type of the whole structure+-}+type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s++-- | Creates 'Lens'' from the getter and setter.+lens :: (s -> a) -> (s -> a -> s) -> Lens' s a+lens getter setter = \f s -> setter s <$> f (getter s)+{-# INLINE lens #-}++-- | Gets a value out of a structure using a getter.+view :: Lens' s a -> s -> a+view l = getConst . l Const+{-# INLINE view #-}++-- | Sets the given value to the structure using a setter.+set :: Lens' s a -> a -> s -> s+set l a = runIdentity . l (const (Identity a))+{-# INLINE set #-}++-- | Applies the given function to the target.+over :: Lens' s a -> (a -> a) -> s -> s+over l fa = runIdentity . l (Identity . fa)+{-# INLINE over #-}++-- | The operator form of 'view' with the arguments flipped.+infixr 4 ^.+(^.) :: s -> Lens' s a -> a+s ^. l = view l s+{-# INLINE (^.) #-}++-- | The operator form of 'set'.+infixr 4 .~+(.~) :: Lens' s a -> a -> s -> s+(.~) = set+{-# INLINE (.~) #-}++-- | The operator form of 'over'.+infixr 4 %~+(%~) :: Lens' s a -> (a -> a) -> s -> s+(%~) = over+{-# INLINE (%~) #-}
src/Relude/Extra/Map.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE TypeFamilies #-}  {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -25,12 +25,13 @@ import GHC.Exts (IsList (Item, toList))  import Relude.Applicative (pure, (*>))-import Relude.Base (Eq, Int, Ord, Type)+import Relude.Base (Eq, Ord, Type) import Relude.Bool (Bool, guard, not) import Relude.Container.Reexport (HashMap, HashSet, Hashable, IntMap, IntSet, Map, Set, fst, snd) import Relude.Function ((.)) import Relude.List (map) import Relude.Monad.Reexport (Maybe (..), fromMaybe)+import Relude.Numeric (Int)  import qualified Data.HashMap.Strict as HM import qualified Data.HashSet as HS
src/Relude/Extra/Newtype.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE ScopedTypeVariables #-}  {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Extra/Tuple.hs view
@@ -1,5 +1,7 @@+{-# LANGUAGE TupleSections #-}+ {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -11,10 +13,12 @@        , mapToFst        , mapToSnd        , mapBoth+       , traverseToFst+       , traverseToSnd+       , traverseBoth        ) where --- $setup--- >>> import Relude+import Relude  {- | Creates a tuple by pairing something with itself. @@ -60,3 +64,47 @@ mapBoth :: (a -> b) -> (a, a) -> (b, b) mapBoth f (a1, a2) = (f a1, f a2) {-# INLINE mapBoth #-}++{- | Apply a function that returns a value inside of a functor,+with the output in the first slot, the input in the second,+and the entire tuple inside the functor.+++A dual to 'traverseToSnd'++>>> traverseToFst (Just . (+1)) 10+Just (11,10)+>>> traverseToFst (const Nothing) 10+Nothing+-}+traverseToFst :: Functor t => (a -> t b) -> a -> t (b, a)+traverseToFst f a = (,a) <$> f a+{-# INLINE traverseToFst #-}++{- | Apply a function that returns a value inside of a functor,+with the output in the second slot, the input in the first,+and the entire tuple inside the functor.++A dual to 'traverseToFst'.++>>> traverseToSnd (Just . (+1)) 10+Just (10,11)+>>> traverseToSnd (const Nothing) 10+Nothing+-}+traverseToSnd :: Functor t => (a -> t b) -> a -> t (a, b)+traverseToSnd f a = (a,) <$> f a+{-# INLINE traverseToSnd #-}++{- | Maps a function that returns a value inside of+an applicative functor over both elements of a tuple,+with the entire tuple inside the applicative functor.++>>> traverseBoth (Just . ("Hello " <>)) ("Alice", "Bob")+Just ("Hello Alice","Hello Bob")+>>> traverseBoth (const Nothing) ("Alice", "Bob")+Nothing+-}+traverseBoth :: Applicative t => (a -> t b) -> (a, a) -> t (b, b)+traverseBoth f (a1, a2) = (,) <$> f a1 <*> f a2+{-# INLINE traverseBoth #-}
src/Relude/Extra/Type.hs view
@@ -4,7 +4,7 @@ {-# LANGUAGE TypeApplications    #-}  {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Extra/Validation.hs view
@@ -3,9 +3,9 @@ {-# LANGUAGE LambdaCase   #-}  {- |-Copyright: (c) 2014 Chris Allen, Edward Kmett-           (c) 2018 Kowainik-License:   MIT+Copyright:  (c) 2014 Chris Allen, Edward Kmett+            (c) 2018-2019 Kowainik+License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com>  Monoidal 'Validation' sibling to 'Either'.
src/Relude/File.hs view
@@ -1,10 +1,17 @@ {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> -Functions to work with files for 'Text', 'LText', 'ByteString' and 'LByteString'-types.+Lifted to 'MonadIO' families of file processing functions for 'Text', 'LText',+'ByteString' and 'LByteString' types.++__NOTE:__ These functions are for working with textual data. Functions that work+with 'Text' or 'LText' types are system and locale-sensitive (encoding,+line-endings). If you want binary data, use 'ByteString' functions (they are+also faster since they don't check encoding). However, you can then decode that+data with the help of functions from the @"Relude.String.Conversion"@ module, e. g.+'Relude.String.Conversion.decodeUtf8'. -}  module Relude.File@@ -47,7 +54,7 @@ readFileText :: MonadIO m => FilePath -> m Text readFileText = liftIO . T.readFile {-# SPECIALIZE readFileText :: FilePath -> IO Text #-}-{-# INLINE readFileText #-}+{-# INLINE     readFileText #-}  -- | Lifted version of 'T.writeFile'. writeFileText :: MonadIO m => FilePath -> Text -> m ()@@ -69,7 +76,7 @@ readFileLText :: MonadIO m => FilePath -> m LText readFileLText = liftIO . LT.readFile {-# SPECIALIZE readFileLText :: FilePath -> IO LText #-}-{-# INLINE readFileLText #-}+{-# INLINE     readFileLText #-}  -- | Lifted version of 'LT.writeFile'. writeFileLText :: MonadIO m => FilePath -> LText -> m ()@@ -91,7 +98,7 @@ readFileBS :: MonadIO m => FilePath -> m ByteString readFileBS = liftIO . BS.readFile {-# SPECIALIZE readFileBS :: FilePath -> IO ByteString #-}-{-# INLINE readFileBS #-}+{-# INLINE     readFileBS #-}  -- | Lifted version of 'BS.writeFile'. writeFileBS :: MonadIO m => FilePath -> ByteString -> m ()@@ -113,7 +120,7 @@ readFileLBS :: MonadIO m => FilePath -> m LByteString readFileLBS = liftIO . LBS.readFile {-# SPECIALIZE readFileLBS :: FilePath -> IO LByteString #-}-{-# INLINE readFileLBS #-}+{-# INLINE     readFileLBS #-}  -- | Lifted version of 'LBS.writeFile'. writeFileLBS :: MonadIO m => FilePath -> LByteString -> m ()
src/Relude/Foldable.hs view
@@ -1,5 +1,5 @@ {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Foldable/Fold.hs view
@@ -5,12 +5,10 @@ {-# LANGUAGE TypeOperators        #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}- {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -19,9 +17,10 @@  module Relude.Foldable.Fold        ( flipfoldl'-       , foldMapA        , asumMap+       , foldMapA        , foldMapM+        , sum        , product @@ -38,20 +37,21 @@        , ElemErrorMessage        ) where -import GHC.TypeLits (ErrorMessage (..), TypeError)+import GHC.TypeLits (ErrorMessage (..), Symbol, TypeError)  import Relude.Applicative (Alternative, Applicative (..), pure)-import Relude.Base (Constraint, Eq, IO, Num (..), Type, ($!))+import Relude.Base (Constraint, Eq, IO, Type, ($!)) import Relude.Bool (Bool (..)) import Relude.Container.Reexport (HashSet, Set) import Relude.Foldable.Reexport (Foldable (..)) import Relude.Function (flip, (.))-import Relude.Functor ((<$>)) import Relude.Monad.Reexport (Monad (..))-import Relude.Monoid (Alt(..), Monoid (..))+import Relude.Monoid (Alt (..), Ap (..), Monoid (..), Semigroup)+import Relude.Numeric (Num (..))  import qualified Data.Foldable as F + -- $setup -- >>> :set -XOverloadedStrings -- >>> import Relude@@ -61,30 +61,31 @@  >>> flipfoldl' (/) 5 [2,3] :: Rational 15 % 2++This function can be useful for constructing containers from lists. -} flipfoldl' :: Foldable f => (a -> b -> b) -> b -> f a -> b flipfoldl' f = foldl' (flip f) {-# INLINE flipfoldl' #-} -{- | Polymorphic version of @concatMapA@ function.-->>> foldMapA @[Int] (Just . replicate 3) [1..3]-Just [1,1,1,2,2,2,3,3,3]--}-foldMapA :: forall b m f a . (Monoid b, Applicative m, Foldable f) => (a -> m b) -> f a -> m b-foldMapA f = foldr step (pure mempty)-  where-    step a mb = mappend <$> f a <*> mb-{-# INLINE foldMapA #-}+{- | Alternative version of @asum@. -{- | Alternative version of @asum@->>> asumMap (\x -> if x > 2 then Just x else Nothing) [1..3]+>>> asumMap (\x -> if x > 2 then Just x else Nothing) [1..4] Just 3 -} asumMap :: (Foldable f, Alternative m) => (a -> m b) -> f a -> m b asumMap f = getAlt . foldMap (Alt . f) {-# INLINE asumMap #-} +{- | Polymorphic version of @concatMapA@ function.++>>> foldMapA @[Int] (Just . replicate 3) [1..3]+Just [1,1,1,2,2,2,3,3,3]+-}+foldMapA :: forall b m f a . (Semigroup b, Monoid b, Applicative m, Foldable f) => (a -> m b) -> f a -> m b+foldMapA f = getAp . foldMap (Ap . f)+{-# INLINE foldMapA #-}+ {- | Polymorphic version of @concatMapM@ function.  >>> foldMapM @[Int] (Just . replicate 3) [1..3]@@ -125,12 +126,12 @@           Instead of               elem :: (Foldable t, Eq a) => a -> t a -> Bool           use-              member :: ??? -- TODO+              member :: Ord a => a -> Set a -> Bool ...           Instead of               notElem :: (Foldable t, Eq a) => a -> t a -> Bool           use-              notMember :: ??? -- TODO+              not . member ... -} elem :: (Foldable f, DisallowElem f, Eq a) => a -> f a -> Bool@@ -148,12 +149,12 @@           Instead of               elem :: (Foldable t, Eq a) => a -> t a -> Bool           use-              member :: ??? -- TODO+              member :: Ord a => a -> Set a -> Bool ...           Instead of               notElem :: (Foldable t, Eq a) => a -> t a -> Bool           use-              notMember :: ??? -- TODO+              not . member ... -} notElem :: (Foldable f, DisallowElem f, Eq a) => a -> f a -> Bool@@ -243,22 +244,29 @@ -- Type level tricks ---------------------------------------------------------------------------- +{- | Type family that produces compile-time errors when 'elem' and 'notElem'+functions are used with 'Set' and 'HashSet'.+-} type family DisallowElem (f :: Type -> Type) :: Constraint where-    DisallowElem     Set = TypeError (ElemErrorMessage Set)-    DisallowElem HashSet = TypeError (ElemErrorMessage HashSet)+    DisallowElem     Set = TypeError (ElemErrorMessage Set SetMemberType)+    DisallowElem HashSet = TypeError (ElemErrorMessage HashSet HashSetMemberType)     DisallowElem f       = () -type family ElemErrorMessage (t :: k) :: ErrorMessage where-    ElemErrorMessage t =-             Text "Do not use 'elem' and 'notElem' methods from 'Foldable' on " :<>: ShowType t-        :$$: Text "Suggestions:"-        :$$: Text "    Instead of"-        :$$: Text "        elem :: (Foldable t, Eq a) => a -> t a -> Bool"-        :$$: Text "    use"-        :$$: Text "        member :: ??? -- TODO"-        :$$: Text ""-        :$$: Text "    Instead of"-        :$$: Text "        notElem :: (Foldable t, Eq a) => a -> t a -> Bool"-        :$$: Text "    use"-        :$$: Text "        notMember :: ??? -- TODO"-        :$$: Text ""++type family ElemErrorMessage (t :: k) (msg :: Symbol) :: ErrorMessage where+    ElemErrorMessage t msg =+              'Text "Do not use 'elem' and 'notElem' methods from 'Foldable' on " ':<>: 'ShowType t+        ':$$: 'Text "Suggestions:"+        ':$$: 'Text "    Instead of"+        ':$$: 'Text "        elem :: (Foldable t, Eq a) => a -> t a -> Bool"+        ':$$: 'Text "    use"+        ':$$: 'Text "        member :: " ':<>: 'Text msg+        ':$$: 'Text ""+        ':$$: 'Text "    Instead of"+        ':$$: 'Text "        notElem :: (Foldable t, Eq a) => a -> t a -> Bool"+        ':$$: 'Text "    use"+        ':$$: 'Text "        not . member"+        ':$$: 'Text ""++type SetMemberType = "Ord a => a -> Set a -> Bool"+type HashSetMemberType = "(Eq a, Hashable a) => a -> HashSet a -> Bool"
src/Relude/Foldable/Reexport.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE CPP #-}  {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -22,9 +22,8 @@                       sequence_, traverse_) import Data.Traversable (Traversable (..), forM, mapAccumL, mapAccumR) #if MIN_VERSION_base(4,10,0)-import Data.Bifoldable (Bifoldable (..), biList, biall, biand,-                        biany, biasum, bielem, bifind, bifoldl', bifoldlM, bifoldr',-                        bifoldrM, bifor_, bilength, binull, bior, bisequence_,-                        bitraverse_)+import Data.Bifoldable (Bifoldable (..), biList, biall, biand, biany, biasum, bielem, bifind,+                        bifoldl', bifoldlM, bifoldr', bifoldrM, bifor_, bilength, binull, bior,+                        bisequence_, bitraverse_) import Data.Bitraversable (Bitraversable (..), bifoldMapDefault, bifor, bimapDefault, bisequence) #endif
src/Relude/Function.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Functor.hs view
@@ -2,7 +2,7 @@  {- | Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell+           (c) 2016-2018 Serokell            (c) 2018 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com>
src/Relude/Functor/Fmap.hs view
@@ -3,7 +3,7 @@  {- | Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell+           (c) 2016-2018 Serokell            (c) 2018 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com>@@ -35,9 +35,9 @@ #endif  -- $setup--- >>> import Relude.Base (negate, (*), (+)) -- >>> import Relude.Monad (Maybe (..)) -- >>> import Relude.List ((++))+-- >>> import Relude.Numeric (negate, (*), (+))  {- | Alias for @fmap . fmap@. Convenient to work with two nested 'Functor's. 
src/Relude/Functor/Reexport.hs view
@@ -3,7 +3,7 @@  {- | Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell+           (c) 2016-2018 Serokell            (c) 2018 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com>
src/Relude/Lifted.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Lifted/Concurrent.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Lifted/Exit.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Lifted/File.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Lifted/IORef.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Lifted/Terminal.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE ExplicitForAll #-}  {- |-Copyright:  (c) 2018 Kowainik+Copyright:  (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/List.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/List/NonEmpty.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/List/Reexport.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Trustworthy #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Monad.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -15,9 +15,25 @@        , module Relude.Monad.Maybe        , module Relude.Monad.Reexport        , module Relude.Monad.Trans+       , chainedTo        ) where  import Relude.Monad.Either import Relude.Monad.Maybe import Relude.Monad.Reexport import Relude.Monad.Trans++-- $setup+-- >>> import Relude++{- | For chaining monadic operations in forward applications using '(&)'+Named version of '=<<'.++>>> Just [ 1 :: Int ] & chainedTo (viaNonEmpty head)+Just 1+>>> Nothing & chainedTo (viaNonEmpty head)+Nothing+-}+chainedTo :: Monad m => (a -> m b) -> m a -> m b+chainedTo = (=<<)+{-# INLINE chainedTo #-}
src/Relude/Monad/Either.hs view
@@ -4,9 +4,9 @@ {-# OPTIONS_GHC -fno-warn-orphans #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Monad/Maybe.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Monad/Reexport.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Monad/Trans.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Safe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Monoid.hs view
@@ -1,7 +1,11 @@+{-# LANGUAGE CPP                        #-}+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -11,9 +15,14 @@ module Relude.Monoid        ( module Data.Monoid        , module Data.Semigroup++       , Ap (..)        , maybeToMonoid        ) where +#if MIN_VERSION_base(4,12,0)+import Data.Monoid (Ap (..))+#endif import Data.Monoid (All (..), Alt (..), Any (..), Dual (..), Endo (..), First (..), Last (..),                     Monoid (..), Product (..), Sum (..)) import Data.Semigroup (Option (..), Semigroup (sconcat, stimes, (<>)), WrappedMonoid, cycle1,@@ -21,9 +30,22 @@  import Relude.Monad.Reexport (Maybe, fromMaybe) +#if !MIN_VERSION_base(4,12,0)+import GHC.Generics (Generic1)++import Relude.Applicative (Alternative, Applicative (..), liftA2)+import Relude.Base (Bounded (..), Enum, Eq, Generic, Ord, Show)+import Relude.Function (($), (.))+import Relude.Functor.Reexport (Functor (..))+import Relude.Monad.Reexport (Monad, MonadFail, MonadPlus)+import Relude.Numeric (Num (..))+import Relude.String.Reexport (Read)+#endif++ -- $setup--- >>> import Relude.Base (Int) -- >>> import Relude.Monad (Maybe (..))+-- >>> import Relude.Numeric (Int)  -- | Extracts 'Monoid' value from 'Maybe' returning 'mempty' if 'Nothing'. --@@ -33,3 +55,48 @@ -- [] maybeToMonoid :: Monoid m => Maybe m -> m maybeToMonoid = fromMaybe mempty++#if !MIN_VERSION_base(4,12,0)+-- | This data type witnesses the lifting of a 'Monoid' into an+-- 'Applicative' pointwise.+--+-- @since 0.5.0+newtype Ap f a = Ap { getAp :: f a }+    deriving ( Alternative+             , Applicative+             , Enum+             , Eq+             , Functor+             , Generic+             , Generic1+             , Monad+             , MonadFail+             , MonadPlus+             , Ord+             , Read+             , Show+             )++-- | @since 0.5.0+instance (Applicative f, Semigroup a) => Semigroup (Ap f a) where+        (Ap x) <> (Ap y) = Ap $ liftA2 (<>) x y++-- | @since 0.5.0+instance (Applicative f, Semigroup a, Monoid a) => Monoid (Ap f a) where+        mempty = Ap $ pure mempty+        mappend = (<>)++-- | @since 0.5.0+instance (Applicative f, Bounded a) => Bounded (Ap f a) where+  minBound = pure minBound+  maxBound = pure maxBound++-- | @since 0.5.0+instance (Applicative f, Num a) => Num (Ap f a) where+  (+)         = liftA2 (+)+  (*)         = liftA2 (*)+  negate      = fmap negate+  fromInteger = pure . fromInteger+  abs         = fmap abs+  signum      = fmap signum+#endif
src/Relude/Nub.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
+ src/Relude/Numeric.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-}++{- |+Copyright:  (c) 2018-2019 Kowainik+License:    MIT+Maintainer: Kowainik <xrom.xkov@gmail.com>+-}++module Relude.Numeric+       ( module Data.Bits+       , module Data.Int+       , module Data.Word+       , module GHC.Base+       , module GHC.Float+       , module GHC.Num+       , module GHC.Real+       , module Numeric.Natural+       , integerToBounded+       , integerToNatural+       ) where++import Data.Bits (toIntegralSized, xor)+import Data.Int (Int, Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8, byteSwap16, byteSwap32, byteSwap64)+import GHC.Base (maxInt, minInt)+import GHC.Float (Double (..), Float (..), Floating (acos, acosh, asin, asinh, atan, atanh, cos, cosh, exp, logBase, pi, sin, sinh, sqrt, tan, tanh, (**)),+                  RealFloat (floatRadix, floatDigits, floatRange, decodeFloat, encodeFloat, isNaN, isInfinite, isDenormalized, isNegativeZero, isIEEE))+import GHC.Num (Integer, Num (..), subtract)+import GHC.Real (Fractional (..), Integral (..), Ratio, Rational, Real (..), RealFrac (..),+                 denominator, even, fromIntegral, gcd, lcm, numerator, odd, realToFrac, (^), (^^))+import Numeric.Natural (Natural)++import Relude.Base (Bounded (..), (<), (>))+import Relude.Bool (otherwise)+import Relude.Function (($))+import Relude.Monad (Maybe (..))+++-- $setup+-- import Relude.Monad (Maybe (..))++{- | Transforms an integer number to a bounded integral.+It returns `Nothing` for integers outside the bound of the return type.++>>> integerToBounded @Int 42+Just 42++>>> integerToBounded @Int8 1024+Nothing++-}+integerToBounded :: forall a. (Integral a, Bounded a) => Integer -> Maybe a+integerToBounded n+    | n < toInteger (minBound @a) = Nothing+    | n > toInteger (maxBound @a) = Nothing+    | otherwise                    = Just (fromIntegral n)++{- | Tranforms an integer number to a natural.+Only non-negative integers are considered natural, everything else will return `Nothing`.++>>> integerToNatural (-1)+Nothing++>>> integerToNatural 0+Just 0++>>> integerToNatural 10+Just 10++-}+integerToNatural :: Integer -> Maybe Natural+integerToNatural n+    | n < 0    = Nothing+    | otherwise = Just $ fromIntegral n
src/Relude/Print.hs view
@@ -4,9 +4,9 @@ {-# LANGUAGE Trustworthy       #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/String.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/String/Conversion.hs view
@@ -6,9 +6,9 @@ {-# LANGUAGE TypeSynonymInstances   #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/String/Reexport.hs view
@@ -1,7 +1,7 @@ {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> 
src/Relude/Unsafe.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE Unsafe #-}  {- |-Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik License:    MIT Maintainer: Kowainik <xrom.xkov@gmail.com> @@ -28,8 +28,8 @@ import Data.List (head, init, last, tail, (!!)) import Data.Maybe (fromJust) -import Relude.Base (Int) import Relude.Function (flip)+import Relude.Numeric (Int)  -- | Similar to '!!' but with flipped arguments. at :: Int -> [a] -> a
test/Doctest.hs view
@@ -1,8 +1,9 @@ {--Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik-License: MIT+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik+License:    MIT+Maintainer: Kowainik <xrom.xkov@gmail.com> -}  module Main (main) where
test/Spec.hs view
@@ -1,8 +1,9 @@ {--Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik-License: MIT+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik+License:    MIT+Maintainer: Kowainik <xrom.xkov@gmail.com> -}  module Main where
test/Test/Relude/Property.hs view
@@ -1,8 +1,9 @@ {--Copyright: (c) 2016 Stephen Diehl-           (c) 20016-2018 Serokell-           (c) 2018 Kowainik-License: MIT+Copyright:  (c) 2016 Stephen Diehl+            (c) 2016-2018 Serokell+            (c) 2018-2019 Kowainik+License:    MIT+Maintainer: Kowainik <xrom.xkov@gmail.com> -}  module Test.Relude.Property