packages feed

relude 0.3.0 → 0.4.0

raw patch · 15 files changed

+456/−77 lines, 15 filesdep −utf8-string

Dependencies removed: utf8-string

Files

CHANGELOG.md view
@@ -1,5 +1,40 @@ # Change log +Unreleased+====++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):+  Drop `utf8-string` dependency and improve performance of conversion functions.+* [#98](https://github.com/kowainik/relude/issues/98):+  Reexport `Bifoldable` related stuff from `base`.+* [#99](https://github.com/kowainik/relude/issues/99):+  Reexport `Bitraversable` related stuff from `base`.+* [#100](https://github.com/kowainik/relude/issues/100):+  Add `Relude.Extra.Validation` with `Validation`data type.+* [#89](https://github.com/kowainik/relude/issues/81):+  Add `Relude.Extra.Type` module containing a `typeName` function.+* [#92](https://github.com/kowainik/relude/issues/92)+  Add `Relude.Extra.Tuple` module, containing+  `dupe`, `mapToFst`, `mapToSnd`, and `mapBoth` functions.+* [#97](https://github.com/kowainik/relude/issues/97):+  Add `(&&^)` and `(||^)` operators.+* [#81](https://github.com/kowainik/relude/issues/81):+  Add `asumMap` to `Foldable` functions.+* [#80](https://github.com/kowainik/relude/issues/80):+  Add hlint rules for `whenLeft`, `whenLeftM`, `whenRight` and `whenRightM`.+* [#79](https://github.com/kowainik/relude/issues/79):+  Add HLint rules for `One` typeclass.+* Remove `openFile` and `hClose`.+* [#83](https://github.com/kowainik/relude/pull/83):+  Make documentation for `nub` functions prettier.+* [#109](https://github.com/kowainik/relude/issues/109):+  Use Dhall v3.0.0 for hlint file generation.+ 0.3.0 ===== 
CONTRIBUTING.md view
@@ -1,53 +1,53 @@-# Contributing to `relude`+# Contributing to the Kowainik repositories  ## :wave: Greetings Traveler! -We're glad you're reading this, we really appreciate the effort you're-putting in. Thank you for your help in making this library awesome! :sparkles:+We are delighted you're reading this, and we appreciate the effort you're+taking to make our projects awesome! :sparkles: -### How to contribute+## How to contribute -#### Report bugs or feature request+### :bug: Report bugs or feature request :bulb: -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/kowainik/relude/issues/new) in free format.+If you discover a bug or have any proposals on how to make this project better+don't hesitate to create an issue [here](../../issues/new) in a free format. -#### Create a PR+### 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 exists 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!+We love to receive pull requests from everyone! It's usually a good idea+to tell about your intention to work on something under the corresponding+issue, so everyone is aware that you're on it. If there's no such issue — simply+create a new one! -To get started with this you should first fork, then clone the repo:+To get started with the Pull Request implementation you should first +[fork](../../fork), then clone the repo: -    git clone git@github.com:your-username/relude.git+    git clone git@github.com:your-username/project-name.git -Make your changes and consider the following check list to go through before submitting your pull request.+Make your changes and consider the following checklist to go through +before submitting your pull request. -#### :white_check_mark: Check list+### :white_check_mark: Check list+- [ ] New/fixed features work as expected (Bonus points for the new tests).+- [ ] There are no warnings during compilation.+- [ ] `hlint .` output is: _No Hints_ (see [`hlint`][hlint] tool docs).+- [ ] The code is formatted with the [`stylish-haskell`][stylish-tool] tool +      using [stylish-haskell.yaml][stylish] file in the repository.+- [ ] The code style of the files you changed is preserved (for more specific +      details on our style guide check [this document][style-guide]).+- [ ] Commit messages are in the proper format.+      Start the first line of the commit with the issue number in square parentheses.+      +    **_Example:_** `[#42] Upgrade upper bounds of 'base'` -- [ ] Project compiles-- [ ] New/fixed features work as expected-- [ ] Old features do not break after the change-- [ ] All new and existing tests pass-- [ ] [`stylish-haskell`](https://github.com/kowainik/org/blob/master/.stylish-haskell.yaml)-      with config in this repo root was used to format code-- [ ] _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`-- [ ] All changes are reflected in `.hlint.yaml` (Use `hlint/hlint.dhall` to make changes).+After all above is done commit and push to your fork.+Now you are ready to [submit a pull request](../../compare). -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:+Thanks for spending your time on reading this contributing guide! :sparkling_heart: -[pr]: https://github.com/kowainik/relude/compare/+[stylish]: .stylish-haskell.yaml+[stylish-tool]: http://hackage.haskell.org/package/stylish-haskell+[hlint]: http://hackage.haskell.org/package/hlint+[style-guide]: https://github.com/kowainik/org/blob/master/style-guide.md#haskell-style-guide
README.md view
@@ -33,7 +33,7 @@ 4. **Minimalism** (low number of dependencies). We don't force users of `relude` to    stick to some specific lens or text formatting or logging library. 5. **Convenience** (like lifted to `MonadIO` functions, more reexports). But we-   want to bring common types and functions (like `containers` and `bytestrng`)+   want to bring common types and functions (like `containers` and `bytestring`)    into scope because they are used in almost every application anyways. 6. **Provide excellent documentation.**    * Tutorial@@ -61,6 +61,7 @@ 3. [Reexports.](#reexports-) 4. [What's new?](#whats-new-) 6. [Migration guide.](#migration-guide-)+7. [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@@ -78,7 +79,8 @@  1. Replace `base` dependency with corresponding version of `base-noprelude` in    your `.cabal` file.-2. Add the following `Prelude` module to your project (both to filesystem and to `exposed-modules`):+2. Add a `relude` dependency to your `.cabal` file.+3. Add the following `Prelude` module to your project (both to filesystem and to `exposed-modules`):    ```haskell    module Prelude           ( module Relude@@ -88,7 +90,7 @@    ```    > **NOTE:** if you use [`summoner`](https://github.com/kowainik/summoner) to generate Haskell project,    > this tool can automatically create such structure for you when you specify custom prelude.-3. Optionally modify your `Prelude` to include more or less functions. Probably+4. Optionally modify your `Prelude` to include more or less functions. Probably    you want to hide something from `Relude` module. Or maybe you want to add    something from `Relude.Extra.*` modules! @@ -291,6 +293,8 @@  * `Foldable1` typeclass that contains generalized interface for folding   non-empty structures like `NonEmpty`.+* `Validation` data type as an alternative to `Either` when you want to combine+  all errors.  Explore `Extra` modules: [`Relude.Extra`](src/Relude/Extra/) @@ -337,9 +341,9 @@    + 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. -### For Developers+## For Developers [↑](#structure-of-this-tutorial) -#### Generating .hlint.yaml+### Generating .hlint.yaml  Note, that we are using custom `hlint` setting which are `Relude` specific. To keep it up to date don't forget to reflect your changes in this file. We are@@ -351,6 +355,9 @@ $ cabal new-install dhall-json ``` +Dhall 3.0.0 is required, so make sure that the previous command installed+dhall-json >= 1.2.4.+ To generate `hlint` file:  ```shell@@ -363,6 +370,11 @@ $ hlint test/Spec.hs ``` -### Acknowledgement+See our blog post where we describe the details of the implementation for this solution:++* [Dhall To HLint](https://kowainik.github.io/posts/2018-09-09-dhall-to-hlint)+++## Acknowledgement  Icons made by [Freepik](http://www.freepik.com) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).
relude.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.0 name:                relude-version:             0.3.0+version:             0.4.0 synopsis:            Custom prelude from Kowainik description:     == Goals@@ -57,6 +57,7 @@ tested-with:         GHC == 8.0.2                    , GHC == 8.2.2                    , GHC == 8.4.3+                   , GHC == 8.6.1 extra-doc-files:     CHANGELOG.md                    , CONTRIBUTING.md                    , README.md@@ -110,13 +111,16 @@                                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.Map                            Relude.Extra.Newtype+                           Relude.Extra.Tuple+                           Relude.Extra.Type+                           Relude.Extra.Validation                            Relude.Unsafe    ghc-options:         -Wall@@ -133,11 +137,10 @@                      , ghc-prim >= 0.4.0.0 && < 0.6                      , hashable ^>= 1.2                      , mtl ^>= 2.2-                     , stm ^>= 2.4+                     , stm >= 2.4 && < 2.6                      , text ^>= 1.2                      , transformers ^>= 0.5                      , unordered-containers >= 0.2.7 && < 0.3-                     , utf8-string ^>= 1.0    default-language:    Haskell2010   default-extensions:  NoImplicitPrelude@@ -154,7 +157,6 @@                      , relude                      , bytestring                      , text-                     , utf8-string                      , hedgehog >= 0.6                      , tasty                      , tasty-hedgehog
src/Relude.hs view
@@ -83,10 +83,15 @@   'CallStack'. * __"Relude.Extra.Enum"__: extra utilities for types that implement 'Bounded'   and 'Enum' constraints.+* __"Relude.Extra.Foldable1"__: 'Foldable1' typeclass like 'Foldable' but for+  non-empty structures. * __"Relude.Extra.Group"__: grouping functions, polymorphic on return @Map@ type. * __"Relude.Extra.Map"__: typeclass for @Map@-like data structures. * __"Relude.Extra.Newtype"__: generic functions that automatically work for any   @newtype@.+* __"Relude.Extra.Tuple"__: functions for working with tuples.+* __"Relude.Extra.Type"__: functions for inspecting and working with types.+* __"Relude.Extra.Validation"__: 'Validation' data type. * __"Relude.Unsafe"__: unsafe partial functions (produce 'error') for lists and   'Maybe'. -}
src/Relude/Bool/Guard.hs view
@@ -13,15 +13,18 @@        , ifM        , unlessM        , whenM+       , (&&^)+       , (||^)        ) where -import Relude.Bool.Reexport (Bool, guard, unless, when)+import Relude.Bool.Reexport (Bool (..), guard, unless, when) import Relude.Function (flip)-import Relude.Monad (Monad, MonadPlus, (>>=))+import Relude.Monad (Monad, return, MonadPlus, (>>=))  -- $setup -- >>> import Relude.Applicative (pure) -- >>> import Relude.Bool.Reexport (Bool (..))+-- >>> import Relude.Debug (error) -- >>> import Relude.Function (($)) -- >>> import Relude.Monad (Maybe (..)) -- >>> import Relude.Print (putTextLn)@@ -73,3 +76,19 @@ guardM :: MonadPlus m => m Bool -> m () guardM f = f >>= guard {-# INLINE guardM #-}++-- | Monadic version of 'Data.Bool.(&&)' operator.+--+-- >>> Just False &&^ error "Shouldn't be evaluated"+-- Just False+(&&^) :: Monad m => m Bool -> m Bool -> m Bool+(&&^) e1 e2 = ifM e1 e2 (return False)+{-# INLINE (&&^) #-}++-- | Monadic version of 'Data.Bool.(||)' operator.+--+-- >>> Just True ||^ error "Shouldn't be evaluated"+-- Just True+(||^) :: Monad m => m Bool -> m Bool -> m Bool+(||^) e1 e2 = ifM e1 (return True) e2+{-# INLINE (||^) #-}
+ src/Relude/Extra/Tuple.hs view
@@ -0,0 +1,62 @@+{- |+Copyright:  (c) 2018 Kowainik+License:    MIT+Maintainer: Kowainik <xrom.xkov@gmail.com>++Contains utility functions for working with tuples.+-}++module Relude.Extra.Tuple+       ( dupe+       , mapToFst+       , mapToSnd+       , mapBoth+       ) where++-- $setup+-- >>> import Relude++{- | Creates a tuple by pairing something with itself.++>>> dupe "foo"+("foo","foo")+>>> dupe ()+((),())+-}+dupe :: a -> (a, a)+dupe a = (a, a)+{-# INLINE dupe #-}++{- | Apply a function, with the result in the fst slot,+and the value in the other.+++A dual to 'mapToSnd'++>>> mapToFst (+1) 10+(11,10)+-}+mapToFst :: (a -> b) -> a -> (b, a)+mapToFst f a = (f a, a)+{-# INLINE mapToFst #-}++{- | Apply a function, with the result in the second slot,+and the value in the other.++A dual to 'mapToFst'.++>>> mapToSnd (+1) 10+(10,11)+-}+mapToSnd :: (a -> b) -> a -> (a, b)+mapToSnd f a = (a, f a)+{-# INLINE mapToSnd #-}++{- | Maps a function over both elements of a tuple.++>>> mapBoth ("Hello " <>) ("Alice", "Bob")+("Hello Alice","Hello Bob")+-}+mapBoth :: (a -> b) -> (a, a) -> (b, b)+mapBoth f (a1, a2) = (f a1, f a2)+{-# INLINE mapBoth #-}
+ src/Relude/Extra/Type.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP                 #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-}++{- |+Copyright:  (c) 2018 Kowainik+License:    MIT+Maintainer: Kowainik <xrom.xkov@gmail.com>++Contains useful functions to work with Types.+-}++module Relude.Extra.Type+       ( typeName+       ) where++import Relude++#if ( __GLASGOW_HASKELL__ >= 822 )+import Type.Reflection (Typeable, typeRep)+#else+import Data.Typeable (Typeable, typeRep)+#endif++{- | Gets a string representation of a type.++__NOTE:__ This must be used with __TypeApplications__ language extension.++>>> typeName @()+"()"+>>> typeName @Int+"Int"+>>> typeName @String+"[Char]"+>>> typeName @(Maybe Int)+"Maybe Int"+-}+typeName :: forall a. Typeable a => Text+#if ( __GLASGOW_HASKELL__ >= 822 )+typeName = show (typeRep @a)+#else+typeName = show (typeRep (Proxy @a))+#endif+{-# INLINE typeName #-}
+ src/Relude/Extra/Validation.hs view
@@ -0,0 +1,182 @@+{-# LANGUAGE CPP          #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE LambdaCase   #-}++{- |+Copyright: (c) 2014 Chris Allen, Edward Kmett+           (c) 2018 Kowainik+License:   MIT+Maintainer: Kowainik <xrom.xkov@gmail.com>++Monoidal 'Validation' sibling to 'Either'.+-}++module Relude.Extra.Validation+       ( Validation(..)+       , validationToEither+       , eitherToValidation+       ) where++import Relude++-- $setup+-- >>> :set -XTypeApplications -XOverloadedStrings++-- | 'Validation' is 'Either' with a Left that is a 'Monoid'+data Validation e a+    = Failure e+    | Success a+    deriving (Eq, Ord, Show)++instance Functor (Validation e) where+    fmap :: (a -> b) -> Validation e a -> Validation e b+    fmap _ (Failure e) = Failure e+    fmap f (Success a) = Success (f a)+    {-# INLINE fmap #-}++    (<$) :: a -> Validation e b -> Validation e a+    x <$ Success _ = Success x+    _ <$ Failure e = Failure e+    {-# INLINE (<$) #-}++{- | __Examples__++>>> let fa = Success (*3) :: Validation [Text] (Int -> Int)+>>> let ga = Success (*4) :: Validation [Text] (Int -> Int)+>>> let a = Success 1 :: Validation [Text] Int+>>> let b = Success 7 :: Validation [Text] Int+>>> let c = Failure ["Not correct"] :: Validation [Text] Int+>>> let d = Failure ["Not correct either"] :: Validation [Text] Int++>>> fa <*> b+Success 21++>>> fa <*> c+Failure ["Not correct"]++>>> c *> d *> b+Failure ["Not correct","Not correct either"]++>>> liftA2 (+) a b+Success 8++>>> liftA2 (+) a c+Failure ["Not correct"]+-}+instance Semigroup e => Applicative (Validation e) where+    pure :: a -> Validation e a+    pure = Success+    {-# INLINE pure #-}++#if MIN_VERSION_base(4,10,0)+    liftA2 :: (a -> b -> c) -> Validation e a -> Validation e b -> Validation e c+    liftA2 _ (Failure el) (Failure er) = Failure (el <> er)+    liftA2 _ (Failure e)  (Success _)  = Failure e+    liftA2 _ (Success _)  (Failure e)  = Failure e+    liftA2 f (Success a)  (Success b)  = Success (f a b)+    {-# INLINE liftA2 #-}+#endif++    (<*>) :: Validation e (a -> b) -> Validation e a -> Validation e b+    Failure e <*> b = Failure $ case b of+                                  Failure e' -> e <> e'+                                  Success _  -> e+    Success _ <*> Failure e  = Failure e+    Success f <*> Success a = Success (f a)+    {-# INLINE (<*>) #-}++    (*>) :: Validation e a -> Validation e b -> Validation e b+    Failure el *> Failure er = Failure (el <> er)+    Failure e  *> Success _  = Failure e+    Success _  *> Failure e  = Failure e+    Success _  *> Success b  = Success b+    {-# INLINE (*>) #-}++    (<*) :: Validation e a -> Validation e b -> Validation e a+    Failure el <* Failure er = Failure (el <> er)+    Failure e  <* Success _  = Failure e+    Success _  <* Failure e  = Failure e+    Success a  <* Success _  = Success a+    {-# INLINE (<*) #-}++instance (Semigroup e, Monoid e) => Alternative (Validation e) where+    empty :: Validation e a+    empty = Failure mempty+    {-# INLINE empty #-}++    (<|>) :: Validation e a -> Validation e a -> Validation e a+    s@Success{} <|> _ = s+    _ <|> s@Success{} = s+    Failure e <|> Failure e' = Failure (e <> e')+    {-# INLINE (<|>) #-}++instance Foldable (Validation e) where+    fold :: Monoid m => Validation e m -> m+    fold (Success a) = a+    fold (Failure _) = mempty+    {-# INLINE fold #-}++    foldMap :: Monoid m => (a -> m) -> Validation e a -> m+    foldMap _ (Failure _) = mempty+    foldMap f (Success a) = f a+    {-# INLINE foldMap #-}++    foldr :: (a -> b -> b) -> b -> Validation e a -> b+    foldr f x (Success a) = f a x+    foldr _ x (Failure _) = x+    {-# INLINE foldr #-}++instance Traversable (Validation e) where+    traverse :: Applicative f => (a -> f b) -> Validation e a -> f (Validation e b)+    traverse f (Success a) = Success <$> f a+    traverse _ (Failure e) = pure (Failure e)+    {-# INLINE traverse #-}++    sequenceA :: Applicative f => Validation e (f a) -> f (Validation e a)+    sequenceA = traverse id+    {-# INLINE sequenceA #-}++instance Bifunctor Validation where+    bimap :: (e -> d) -> (a -> b) -> Validation e a -> Validation d b+    bimap f _ (Failure e) = Failure (f e)+    bimap _ g (Success a) = Success (g a)+    {-# INLINE bimap #-}++    first :: (e -> d) -> Validation e a -> Validation d a+    first f (Failure e) = Failure (f e)+    first _ (Success a) = Success a+    {-# INLINE first #-}++    second :: (a -> b) -> Validation e a -> Validation e b+    second _ (Failure e) = Failure e+    second g (Success a) = Success (g a)+    {-# INLINE second #-}++#if MIN_VERSION_base(4,10,0)+instance Bifoldable Validation where+    bifoldMap :: Monoid m => (e -> m) -> (a -> m) -> Validation e a -> m+    bifoldMap f _ (Failure e) = f e+    bifoldMap _ g (Success a) = g a+    {-# INLINE bifoldMap #-}++instance Bitraversable Validation where+    bitraverse :: Applicative f+               => (e -> f d) -> (a -> f b) -> Validation e a -> f (Validation d b)+    bitraverse f _ (Failure e) = Failure <$> f e+    bitraverse _ g (Success a) = Success <$> g a+    {-# INLINE bitraverse #-}+#endif++-- | Transform a 'Validation' into an 'Either'.+validationToEither :: Validation e a -> Either e a+validationToEither = \case+    Failure e -> Left e+    Success a -> Right a+{-# INLINE validationToEither #-}++-- | Transform an 'Either' into a 'Validation'.+eitherToValidation :: Either e a -> Validation e a+eitherToValidation = \case+    Left e  -> Failure e+    Right a -> Success a+{-# INLINE eitherToValidation #-}
src/Relude/Foldable/Fold.hs view
@@ -20,6 +20,7 @@ module Relude.Foldable.Fold        ( flipfoldl'        , foldMapA+       , asumMap        , foldMapM        , sum        , product@@ -39,7 +40,7 @@  import GHC.TypeLits (ErrorMessage (..), TypeError) -import Relude.Applicative (Applicative (..), pure)+import Relude.Applicative (Alternative, Applicative (..), pure) import Relude.Base (Constraint, Eq, IO, Num (..), Type, ($!)) import Relude.Bool (Bool (..)) import Relude.Container.Reexport (HashSet, Set)@@ -47,7 +48,7 @@ import Relude.Function (flip, (.)) import Relude.Functor ((<$>)) import Relude.Monad.Reexport (Monad (..))-import Relude.Monoid (Monoid (..))+import Relude.Monoid (Alt(..), Monoid (..))  import qualified Data.Foldable as F @@ -75,6 +76,14 @@   where     step a mb = mappend <$> f a <*> mb {-# INLINE foldMapA #-}++{- | Alternative version of @asum@+>>> asumMap (\x -> if x > 2 then Just x else Nothing) [1..3]+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 @concatMapM@ function. 
src/Relude/Foldable/Reexport.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ {- | Copyright:  (c) 2018 Kowainik License:    MIT@@ -9,9 +11,20 @@ module Relude.Foldable.Reexport        ( module Data.Foldable        , module Data.Traversable+#if MIN_VERSION_base(4,10,0)+       , module Data.Bifoldable+       , module Data.Bitraversable+#endif        ) where  import Data.Foldable (Foldable (fold, foldMap, foldl', foldr, length, null, toList), all, and, any,                       asum, concat, concatMap, find, foldlM, forM_, for_, mapM_, or, sequenceA_,                       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.Bitraversable (Bitraversable (..), bifoldMapDefault, bifor, bimapDefault, bisequence)+#endif
src/Relude/Functor/Reexport.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP  #-} {-# LANGUAGE Safe #-}  {- |@@ -15,9 +16,18 @@        , module Data.Functor        , module Data.Functor.Compose        , module Data.Functor.Identity+#if MIN_VERSION_base(4,12,0)+       , module Data.Functor.Contravariant+#endif        ) where  import Data.Bifunctor (Bifunctor (..)) import Data.Functor (Functor (..), void, ($>), (<$>)) import Data.Functor.Compose (Compose (..)) import Data.Functor.Identity (Identity (..))++#if MIN_VERSION_base(4,12,0)+import Data.Functor.Contravariant (Comparison (..), Contravariant (..), Equivalence (..), Op (..),+                                   Predicate (..), comparisonEquivalence, defaultComparison,+                                   defaultEquivalence, phantom, ($<), (>$$<), (>$<))+#endif
src/Relude/Lifted/File.hs view
@@ -12,11 +12,9 @@        ( readFile        , writeFile        , appendFile-       , openFile-       , hClose        ) where -import Relude.Base (FilePath, Handle, IO, IOMode, String)+import Relude.Base (FilePath, IO, String) import Relude.Function ((.)) import Relude.Monad.Reexport (MonadIO (..)) @@ -40,15 +38,3 @@ appendFile p = liftIO . IO.appendFile p {-# SPECIALIZE appendFile :: FilePath -> String -> IO () #-} {-# INLINE appendFile #-}---- | Lifted version of 'IO.openFile'.-openFile :: MonadIO m => FilePath -> IOMode -> m Handle-openFile p = liftIO . IO.openFile p-{-# SPECIALIZE openFile :: FilePath -> IOMode -> IO Handle #-}-{-# INLINE openFile #-}---- | Lifted version of 'IO.hClose'.-hClose :: MonadIO m => Handle -> m ()-hClose = liftIO . hClose-{-# SPECIALIZE hClose :: Handle -> IO () #-}-{-# INLINE hClose #-}
src/Relude/Nub.hs view
@@ -43,7 +43,7 @@  import qualified Data.Set as Set -{- | Like 'Prelude.nub' but runs in @O(n * log n)@ time and requires 'Ord'.+{- | Like 'Prelude.nub' but runs in \( O(n \log n) \)  time and requires 'Ord'.  >>> ordNub [3, 3, 3, 2, 2, -1, 1] [3,2,-1,1]@@ -58,7 +58,7 @@       then go s xs       else x : go (Set.insert x s) xs -{- | Like 'Prelude.nub' but runs in @O(n * log_16(n))@ time and requires 'Hashable'.+{- | Like 'Prelude.nub' but runs in \( O(n \log_{16} n) \)  time and requires 'Hashable'.  >>> hashNub [3, 3, 3, 2, 2, -1, 1] [3,2,-1,1]@@ -73,7 +73,7 @@       then go s xs       else x : go (HashSet.insert x s) xs -{- | Like 'ordNub' but also sorts a list.+{- | Like 'ordNub' runs in \( O(n \log n) \)  but also sorts a list.  >>> sortNub [3, 3, 3, 2, 2, -1, 1] [-1,1,2,3]@@ -82,7 +82,7 @@ sortNub :: (Ord a) => [a] -> [a] sortNub = Set.toList . Set.fromList -{- | Like 'hashNub' but has better performance and also doesn't save the order.+{- | Like 'hashNub' runs in \( O(n \log_{16} n) \) but has better performance; it doesn't save the order.  >>> unstableNub [3, 3, 3, 2, 2, -1, 1] [1,2,3,-1]
src/Relude/String/Conversion.hs view
@@ -48,8 +48,6 @@  import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as LB-import qualified Data.ByteString.Lazy.UTF8 as LBU-import qualified Data.ByteString.UTF8 as BU import qualified Data.Text as T import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding.Error as T@@ -101,8 +99,8 @@     decodeUtf8Strict :: b -> Either T.UnicodeException a  instance ConvertUtf8 String B.ByteString where-    encodeUtf8 = BU.fromString-    decodeUtf8 = BU.toString+    encodeUtf8 = T.encodeUtf8 . T.pack+    decodeUtf8 = T.unpack . T.decodeUtf8     decodeUtf8Strict = (T.unpack <$>) . decodeUtf8Strict  instance ConvertUtf8 T.Text B.ByteString where@@ -114,10 +112,11 @@     encodeUtf8 = LB.toStrict . encodeUtf8     decodeUtf8 = LT.decodeUtf8With T.lenientDecode . LB.fromStrict     decodeUtf8Strict = decodeUtf8Strict . LB.fromStrict-+-- | Converting 'String' to 'LB.ByteString' might be a slow operation.+-- Consider using lazy bytestring at first place. instance ConvertUtf8 String LB.ByteString where-    encodeUtf8 = LBU.fromString-    decodeUtf8 = LBU.toString+    encodeUtf8 = LT.encodeUtf8 . LT.pack+    decodeUtf8 = LT.unpack . LT.decodeUtf8     decodeUtf8Strict = (T.unpack <$>) . decodeUtf8Strict  instance ConvertUtf8 T.Text LB.ByteString where