relude 1.2.0.0 → 1.2.1.0
raw patch · 10 files changed
+474/−392 lines, 10 filesdep ~basedep ~containersdep ~deepseq
Dependency ranges changed: base, containers, deepseq, doctest, ghc-prim, hashable, hedgehog, text
Files
- CHANGELOG.md +234/−207
- README.md +176/−165
- relude.cabal +12/−11
- src/Relude/Debug.hs +9/−2
- src/Relude/Extra/Foldable1.hs +10/−4
- src/Relude/Extra/Type.hs +6/−0
- src/Relude/Foldable/Fold.hs +6/−0
- src/Relude/List/NonEmpty.hs +5/−0
- src/Relude/String/Conversion.hs +11/−3
- src/Relude/String/Reexport.hs +5/−0
CHANGELOG.md view
@@ -3,32 +3,46 @@ `relude` uses [PVP Versioning][1]. The changelog is available [on GitHub][2]. +## 1.2.1.0 – Oct 4, 2023++- [#439](https://github.com/kowainik/relude/issues/439):+ Support GHC-9.6.+- Upgrade dependencies. Allow:+ - `ghc-prim-0.10`+ - `text-2.1`+ - `bytestring-2.12`+ - `containers-0.7`+ - `deepseq-1.5`+ - `hedgehod-1.3`+ - `doctest-0.22`+- Upgrade tests to work with GHC-9.6.+ ## 1.2.0.0 – Mar 1, 2023 -* [#420](https://github.com/kowainik/relude/issues/420):+- [#420](https://github.com/kowainik/relude/issues/420): Support GHC-9.4.-* Reexport `type (~)` from `Data.Type.Equality` for GHC-9.4.-* Add `-Wredundant-strictness-flags` and `-Wforall-identifier` warnings for+- Reexport `type (~)` from `Data.Type.Equality` for GHC-9.4.+- Add `-Wredundant-strictness-flags` and `-Wforall-identifier` warnings for GHC-9.4.-* [#430](https://github.com/kowainik/relude/issues/430):+- [#430](https://github.com/kowainik/relude/issues/430): Upgrade dependencies:- - `ghc-prim-0.9`- - `mtl-2.3`- - `hedgehog-1.2`- - `doctest-0.21`-* Drop support of GHC-8.2.+ - `ghc-prim-0.9`+ - `mtl-2.3`+ - `hedgehog-1.2`+ - `doctest-0.21`+- Drop support of GHC-8.2. ## 1.1.0.0 — Jun 9, 2022 -* [#388](https://github.com/kowainik/relude/issues/388):+- [#388](https://github.com/kowainik/relude/issues/388): Support GHC-9.2.-* [#363](https://github.com/kowainik/relude/issues/363):+- [#363](https://github.com/kowainik/relude/issues/363): Remove the `Option` type, reexported from `Data.Semigroup` (which was removed in `base-4.16`, GHC 9.2) **Migration guide:** Use `Maybe` instead of `Option`. -* [#372](https://github.com/kowainik/relude/issues/372):+- [#372](https://github.com/kowainik/relude/issues/372): Warn on usages of `readFileText`, `readFileLText`, `readFile` and `readFile'`. > _NOTE:_ This is a **breaking change** if you build with `-Werror`@@ -36,28 +50,28 @@ > instead to convert to `Text` / `LText` / `String` using > `decodeUtf8` and similar functions. -* [#394](https://github.com/kowainik/relude/issues/394):+- [#394](https://github.com/kowainik/relude/issues/394): Support `hashable-1.4`.-* [#408](https://github.com/kowainik/relude/issues/408):+- [#408](https://github.com/kowainik/relude/issues/408): Switch benchmarks from `criterion` to `tasty-bench`.-* [#404](https://github.com/kowainik/relude/issues/404):+- [#404](https://github.com/kowainik/relude/issues/404): Fix condidion for `ordNubOn`, `intNub`, `intNubOn` export for `Relude.Nub` module.- Use min version of `containers-0.6.0` instead of min version of GHC `8.4`. -* Minor documentation improvements and fixes.+ Use min version of `containers-0.6.0` instead of min version of GHC `8.4`.+- Minor documentation improvements and fixes. ## 1.0.0.1 — Mar 15, 2021 -* Minor documentation changes.+- Minor documentation changes. ## 1.0.0.0 — Mar 12, 2021 -* [#353](https://github.com/kowainik/relude/issues/353):+- [#353](https://github.com/kowainik/relude/issues/353): Reexport most common modules from the following libraries: - + `containers`- + `unordered-containers`- + `text`- + `bytestring`+ - `containers`+ - `unordered-containers`+ - `text`+ - `bytestring` Now, when using `relude`, you don't need to add these libraries to your `.cabal` file to enjoy their main API. Try removing them from@@ -73,158 +87,164 @@ , relude ``` -* [#345](https://github.com/kowainik/relude/issues/345):+- [#345](https://github.com/kowainik/relude/issues/345): Support GHC-9.0.-* Upgrade minor GHC versions to GHC-8.10.4 and GHC-8.8.4.-* [#268](https://github.com/kowainik/relude/issues/268):+- Upgrade minor GHC versions to GHC-8.10.4 and GHC-8.8.4.+- [#268](https://github.com/kowainik/relude/issues/268): Drop support of GHC-8.0.2.-* [#270](https://github.com/kowainik/relude/issues/270):+- [#270](https://github.com/kowainik/relude/issues/270): Standardise `universe`, `universeNonEmpty` and `inverseMap` functions that previously were introduced in the `Relude.Extra.Enum` module. `Relude.Enum` module created that is exported in the main `Relude` module by default. - __Migration guide:__ If you were using any of these functions you can now+ **Migration guide:** If you were using any of these functions you can now remove `Relude.Extra.Enum` from your imports and explicit `mixins` section as they are available for you with the `Relude` module.-* Remove the `Eq` constraint on `universeNonEmpty`-* [#269](https://github.com/kowainik/relude/issues/269):++- Remove the `Eq` constraint on `universeNonEmpty`+- [#269](https://github.com/kowainik/relude/issues/269): Remove the `Relude.Extra.Validation` module. - __Migration guide:__+ **Migration guide:** If you use `Relude.Extra.Validation` in you project you need to: - 1. Add `validation-selective` into the `build-depends` section of your- `.cabal` file.- 2. Change imports of `Relude.Extra.Validation` to `Validation`:+ 1. Add `validation-selective` into the `build-depends` section of your+ `.cabal` file.+ 2. Change imports of `Relude.Extra.Validation` to `Validation`: - ```haskell- -- Was:- import Relude.Extra.Validation (Validation (..), ..)- -- Became:- import Validation (Validation (..), ..)- ```+ ```haskell+ -- Was:+ import Relude.Extra.Validation (Validation (..), ..)+ -- Became:+ import Validation (Validation (..), ..)+ ``` -* [#346](https://github.com/kowainik/relude/issues/346),+- [#346](https://github.com/kowainik/relude/issues/346), [#347](https://github.com/kowainik/relude/issues/347): Reimplement `ordNub` through `nubOrd` from `containers`. Add `ordNubOn`, `intNub` and `intNubOn` functions.-* [#327](https://github.com/kowainik/relude/issues/327):+- [#327](https://github.com/kowainik/relude/issues/327): Add `infinitely` as more strictly typed `forever`.-* [#311](https://github.com/kowainik/relude/issues/311):+- [#311](https://github.com/kowainik/relude/issues/311): Add `maybeAt` function — the non-operator version of `!!?` with its arguments flipped.-* [#314](https://github.com/kowainik/relude/issues/314):+- [#314](https://github.com/kowainik/relude/issues/314): Add lifted versions of functions to work with `Handle`: - + `hFlush`- + `hIsEOF`- + `hSetBuffering`- + `hGetBuffering`-* [#305](https://github.com/kowainik/relude/issues/305):+ - `hFlush`+ - `hIsEOF`+ - `hSetBuffering`+ - `hGetBuffering`++- [#305](https://github.com/kowainik/relude/issues/305): Add lifted versions of functions to work with environment: - + `getArgs`- + `lookupEnv`-* Add lifted version of the `readFile'` function.-* Reexport the `BufferMode` type from `base`.-* [#309](https://github.com/kowainik/relude/issues/309):+ - `getArgs`+ - `lookupEnv`++- Add lifted version of the `readFile'` function.+- Reexport the `BufferMode` type from `base`.+- [#309](https://github.com/kowainik/relude/issues/309): Reexport `span` from `Data.List`.-* [#319](https://github.com/kowainik/relude/issues/319):+- [#319](https://github.com/kowainik/relude/issues/319): Implement `partitionWith`.-* [#307](https://github.com/kowainik/relude/issues/307):+- [#307](https://github.com/kowainik/relude/issues/307): Add `foldr1` to `Foldable1`.-* [#316](https://github.com/kowainik/relude/issues/316):+- [#316](https://github.com/kowainik/relude/issues/316): Add `average` and `average1` — efficient functions for finding average on foldable structures.-* [#306](https://github.com/kowainik/relude/issues/306):+- [#306](https://github.com/kowainik/relude/issues/306): Add `maximumOn1` and `minimumOn1` to `Foldable1`.-* [#301](https://github.com/kowainik/relude/issues/301):+- [#301](https://github.com/kowainik/relude/issues/301): Add `traceShowWith` to `Relude.Debug`.-* [#304](https://github.com/kowainik/relude/issues/304),+- [#304](https://github.com/kowainik/relude/issues/304), [#317](https://github.com/kowainik/relude/issues/317): Various documentation improvements.-* Updates to `relude`-specific `.hlint` rules.+- Updates to `relude`-specific `.hlint` rules. Thanks @googleson78, @sushi-shi, @rektrex, @aleator, @mjgpy3, @dalpd, @Bodigrim for helping with this release! ## 0.7.0.0 — May 14, 2020 -* [#253](https://github.com/kowainik/relude/issues/253):+- [#253](https://github.com/kowainik/relude/issues/253): Support GHC-8.10. Upgrade GHC-8.8 to 8.8.3.-* Significant documentation improvements:- + Add high-level description to each reexported module.- + Add String Conversion Table.- + Add `NonEmpty` lists functions tables.- + Add `@since` annotations.- + Improve README.- + Inline some external reexports into explicit lists of exports.- + Rewrite top-level `cabal` description.-* [#234](https://github.com/kowainik/relude/issues/234):+- Significant documentation improvements:+ - Add high-level description to each reexported module.+ - Add String Conversion Table.+ - Add `NonEmpty` lists functions tables.+ - Add `@since` annotations.+ - Improve README.+ - Inline some external reexports into explicit lists of exports.+ - Rewrite top-level `cabal` description.+- [#234](https://github.com/kowainik/relude/issues/234): Reexport `scanl1`, `scanr1`, `scanl'` from `Data.List`.-* [#256](https://github.com/kowainik/relude/issues/256):+- [#256](https://github.com/kowainik/relude/issues/256): Make `cycle` total function.-* [#233](https://github.com/kowainik/relude/issues/233):+- [#233](https://github.com/kowainik/relude/issues/233): Add `etaReaderT` to `Relude.Monad.Trans` to help with performance.-* [#294](https://github.com/kowainik/relude/issues/294):+- [#294](https://github.com/kowainik/relude/issues/294): Add `atomicModifyIORef_` and `atomicModifyIORef'_`.-* [#293](https://github.com/kowainik/relude/issues/293):+- [#293](https://github.com/kowainik/relude/issues/293): Add `memptyIfFalse` and `memptyIfTrue` functions.-* Reexport `NonEmpty` functions from `Relude.List.NonEmpty` instead of+- Reexport `NonEmpty` functions from `Relude.List.NonEmpty` instead of `Relude.List.Reexport`.-* [#239](https://github.com/kowainik/relude/issues/239):+- [#239](https://github.com/kowainik/relude/issues/239): Reexport more STM functions that work with `TMVar` from `Relude.Lifted.Concurrent`.-* [#227](https://github.com/kowainik/relude/issues/227):+- [#227](https://github.com/kowainik/relude/issues/227): Create `Relude.Extra` module-* [#228](https://github.com/kowainik/relude/issues/228):+- [#228](https://github.com/kowainik/relude/issues/228): Add `universeNonEmpty` function.-* [#249](https://github.com/kowainik/relude/issues/249):- __Breaking change:__ Fix infix of the `Relude.Extra.Lens` `(^.)` operator.+- [#249](https://github.com/kowainik/relude/issues/249):+ **Breaking change:** Fix infix of the `Relude.Extra.Lens` `(^.)` operator. Change it to `infixl 8`.-* Reexport partial `read` from `Relude.Unsafe` for consistency.-* [#244](https://github.com/kowainik/relude/issues/244):+- Reexport partial `read` from `Relude.Unsafe` for consistency.+- [#244](https://github.com/kowainik/relude/issues/244): Remove deprecated functions: `prec`, `dupe` and `mapBoth`. - __Migration rules:__- + `prec`: use `prev` instead- + `dupe`: use `dup` instead- + `mapBoth`: use `bimapBoth` instead+ **Migration rules:** -* [#246](https://github.com/kowainik/relude/issues/246):+ - `prec`: use `prev` instead+ - `dupe`: use `dup` instead+ - `mapBoth`: use `bimapBoth` instead++- [#246](https://github.com/kowainik/relude/issues/246): Deprecate `Relude.Extra.Validation` in favour of [`validation-selective`](https://hackage.haskell.org/package/validation-selective) - __Migration rules:__+ **Migration rules:** If you use `Relude.Extra.Validation` in you project you need to: - 1. Add `validation-selective` into the `build-depends` section of your- `.cabal` file.- 2. Change imports of `Relude.Extra.Validation` to `Validation`:+ 1. Add `validation-selective` into the `build-depends` section of your+ `.cabal` file.+ 2. Change imports of `Relude.Extra.Validation` to `Validation`: - ```haskell- -- Was:- import Relude.Extra.Validation (Validation (..), ..)- -- Became:- import Validation (Validation (..), ..)- ```-* [#196](https://github.com/kowainik/relude/issues/196):+ ```haskell+ -- Was:+ import Relude.Extra.Validation (Validation (..), ..)+ -- Became:+ import Validation (Validation (..), ..)+ ```++- [#196](https://github.com/kowainik/relude/issues/196): Deprecate `mapToFst` and `mapToSnd`. Introduce `toFst` and `toSnd` in `Relude.Extra.Tuple` as shorter aliases for `mapToFst`. Implement `fmapToFst` and `fmapToSnd`. Add more HLint rules for `Relude.Extra.Tuple` functions. - __Migration rules:__+ **Migration rules:** - + Replace `mapToFst` with `toFst`- + Replace `mapToSnd` with `toSnd`- + You can now use `fmapToFst` and `fmapToSnd` instead of+ - Replace `mapToFst` with `toFst`+ - Replace `mapToSnd` with `toSnd`+ - You can now use `fmapToFst` and `fmapToSnd` instead of `[f]map (mapToFst f)` and `[f]map (mapToSnd f)`-* [#286](https://github.com/kowainik/relude/issues/286):- __Breaking change:__ `readEither` is not polymorphic over the first argument++- [#286](https://github.com/kowainik/relude/issues/286):+ **Breaking change:** `readEither` is not polymorphic over the first argument anymore. Now it takes `String`. - __Migration rules:__ Use one of the conversion function from the+ **Migration rules:** Use one of the conversion function from the `Relude.String.Conversion` module to covert your old input value into `String`. @@ -240,92 +260,96 @@ readEither @Int (toString myText) ``` -* [#281](https://github.com/kowainik/relude/issues/281):+- [#281](https://github.com/kowainik/relude/issues/281): Move `One` property tests from `doctest` to `hedgehog`. Significant test time boost.-* [#264](https://github.com/kowainik/relude/issues/264):+- [#264](https://github.com/kowainik/relude/issues/264): Support Dhall-16.0.0 in HLint rules. ## 0.6.0.0 — Oct 30, 2019 -* [#171](https://github.com/kowainik/relude/issues/171):+- [#171](https://github.com/kowainik/relude/issues/171): Add custom type errors to various functions and instances.- + `head`, `tail`, `last`, `init`- + `words`, `unwords`, `lines`, `unlines`- + `error`- + `ToText`, `ToLText`, `ToString` instances for bytestrings- + `Foldable1` instance for ordinary lists- + `Monad` instance for `Validation` + - `head`, `tail`, `last`, `init`+ - `words`, `unwords`, `lines`, `unlines`+ - `error`+ - `ToText`, `ToLText`, `ToString` instances for bytestrings+ - `Foldable1` instance for ordinary lists+ - `Monad` instance for `Validation`+ (by [@vrom911](https://github.com/vrom911), [@chshersh](https://github.com/chshersh))-* [#164](https://github.com/kowainik/relude/issues/164):++- [#164](https://github.com/kowainik/relude/issues/164): Reexport `ShortByteString`, `toShort`/`fromShort` functions. (by [@vrom911](https://github.com/vrom911))-* [#182](https://github.com/kowainik/relude/issues/182):+- [#182](https://github.com/kowainik/relude/issues/182): Support GHC-8.8.1. (by [@chshersh](https://github.com/chshersh))-* [#168](https://github.com/kowainik/relude/pull/168),+- [#168](https://github.com/kowainik/relude/pull/168), [#197](https://github.com/kowainik/relude/pull/197): Improve documentation significantly (more and better examples, better wording). (by [@chshersh](https://github.com/chshersh), [@vrom911](https://github.com/vrom911), [@Cmdv](https://github.com/Cmdv))-* [#177](https://github.com/kowainik/relude/issues/177):+- [#177](https://github.com/kowainik/relude/issues/177): Improve usage of performance pragmas. (by [@chshersh](https://github.com/chshersh))-* [#167](https://github.com/kowainik/relude/issues/167):+- [#167](https://github.com/kowainik/relude/issues/167): Rename functions (and deprecate old versions):- + `prec` to `prev`- + `dupe` to `dup` + - `prec` to `prev`+ - `dupe` to `dup`+ (by [@Cmdv](https://github.com/Cmdv), [@chshersh](https://github.com/chshersh))-* [#192](https://github.com/kowainik/relude/issues/192):++- [#192](https://github.com/kowainik/relude/issues/192): Reexport `foldMap'` from `Data.Foldable`. (by [@tfausak](https://github.com/tfausak))-* [#201](https://github.com/kowainik/relude/issues/201):+- [#201](https://github.com/kowainik/relude/issues/201): Implement `!!?` as a safe equivalent of `!!` that returns a `Maybe`. (by [@kutyel](https://github.com/kutyel))-* [#203](https://github.com/kowainik/relude/issues/203):+- [#203](https://github.com/kowainik/relude/issues/203): Implement the `guarded` combinator. (by [@JonathanLorimer](https://github.com/JonathanLorimer))-* [#214](https://github.com/kowainik/relude/issues/214):+- [#214](https://github.com/kowainik/relude/issues/214): Add `mapMaybeM` function. (by [@vrom911](https://github.com/vrom911))-* [#174](https://github.com/kowainik/relude/issues/174):+- [#174](https://github.com/kowainik/relude/issues/174): Implement `bimapBoth` in `Relude.Extra.Tuple` module, mark `mapBoth` as DEPRECATED. (by [@astynax](https://github.com/astynax))-* [#221](https://github.com/kowainik/relude/issues/221):+- [#221](https://github.com/kowainik/relude/issues/221): Improve documentation for the `Validation` module significantly. (by [@chshersh](https://github.com/chshersh))-* [#176](https://github.com/kowainik/relude/issues/176):+- [#176](https://github.com/kowainik/relude/issues/176): Implement property-based tests for `Validation` laws. (by [@astynax](https://github.com/astynax))-* [#172](https://github.com/kowainik/relude/issues/172):+- [#172](https://github.com/kowainik/relude/issues/172): Add `Monoid` and `Semigroup` instances for the `Validation` type. (by [@mauriciofierrom](https://github.com/mauriciofierrom))-* [#156](https://github.com/kowainik/relude/issues/156):+- [#156](https://github.com/kowainik/relude/issues/156): Implement helper type-level functions in `Relude.Extra.Type`. (by [@TheMatten](https://github.com/TheMatten))-* [#170](https://github.com/kowainik/relude/issues/170):+- [#170](https://github.com/kowainik/relude/issues/170): Implement `Elem` type family. (by [@kutyel](https://github.com/kutyel))-* [#165](https://github.com/kowainik/relude/pull/165):+- [#165](https://github.com/kowainik/relude/pull/165): Re-export `GHC.Float.atan2`. (by [@ethercrow](https://github.com/ethercrow))-* [#155](https://github.com/kowainik/relude/issue/155):+- [#155](https://github.com/kowainik/relude/issue/155): Implement `foldlSC` — short-circuting list fold — in `Relude.Extra.Foldable`. (by [@josephcsible](https://github.com/josephcsible))-* [#158](https://github.com/kowainik/relude/issue/158):+- [#158](https://github.com/kowainik/relude/issue/158): Support GHC-8.6.5. (by [@chshersh](https://github.com/chshersh))-* [#148](https://github.com/kowainik/relude/issues/148):+- [#148](https://github.com/kowainik/relude/issues/148): Migrate HLint rules to the latest Dhall spec. (by [@vrom911](https://github.com/vrom911))-* [#178](https://github.com/kowainik/relude/issues/178):+- [#178](https://github.com/kowainik/relude/issues/178): Made `die` be polymorphic in its return type. (by [@ilyakooo0](https://github.com/ilyakooo0))-* [#162](https://github.com/kowainik/relude/pull/162),+- [#162](https://github.com/kowainik/relude/pull/162), [#189](https://github.com/kowainik/relude/pull/189), [#190](https://github.com/kowainik/relude/pull/190), [#191](https://github.com/kowainik/relude/pull/191),@@ -333,83 +357,85 @@ [#194](https://github.com/kowainik/relude/pull/194), [#195](https://github.com/kowainik/relude/pull/195): Various refactorings and code improvements:- + __Breaking change:__ Reorder type parameters to `asumMap`- + Implement `andM`, `orM`, `allM`, and `anyM` in terms of `&&^` and `||^`- + Use `foldr` instead of explicit recursion and `toList`- + Use `mapToFst` instead of `zip` to improve list fusion in `inverseMap`- + Implement `foldMap1` for `NonEmpty` in terms of `foldr`- + Use `$>` instead of `*>` and `pure` where possible- + Implement `asumMap` and `foldMapA` by coercing `foldMap`- + Return Failure early in `<*` and `*>` too + - **Breaking change:** Reorder type parameters to `asumMap`+ - Implement `andM`, `orM`, `allM`, and `anyM` in terms of `&&^` and `||^`+ - Use `foldr` instead of explicit recursion and `toList`+ - Use `mapToFst` instead of `zip` to improve list fusion in `inverseMap`+ - Implement `foldMap1` for `NonEmpty` in terms of `foldr`+ - Use `$>` instead of `*>` and `pure` where possible+ - Implement `asumMap` and `foldMapA` by coercing `foldMap`+ - Return Failure early in `<*` and `*>` too+ (by [@josephcsible](https://github.com/josephcsible))-* [#187](https://github.com/kowainik/relude/issues/187):++- [#187](https://github.com/kowainik/relude/issues/187): Remove `tasty` and `tasty-hedgehog` dependencies and their redundant imports. (by [@dalpd](https://github.com/dalpd)) ## 0.5.0 — Mar 18, 2019 -* [#127](https://github.com/kowainik/relude/issues/127):+- [#127](https://github.com/kowainik/relude/issues/127): Implement `Relude.Extra.Lens` module.-* [#125](https://github.com/kowainik/relude/issues/125):+- [#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):+- [#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):+- [#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):+- [#138](https://github.com/kowainik/relude/issues/138): Add `RealFloat` to `Relude.Numeric`.-* [#144](https://github.com/kowainik/relude/issues/144):+- [#144](https://github.com/kowainik/relude/issues/144): Add `traverseToSnd` and friends to `Relude.Extra.Tuple`.-* [#140](https://github.com/kowainik/relude/issues/140):+- [#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):+- [#136](https://github.com/kowainik/relude/issues/136): Cover `Relude.Extra.*` modules with custom HLint rules.-* [#146](https://github.com/kowainik/relude/issues/146):+- [#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.+- 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):+- [#70](https://github.com/kowainik/relude/issues/70): Reexport `Contravariant` for GHC >= 8.6.1.-* [#103](https://github.com/kowainik/relude/pull/104):+- [#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):+- [#98](https://github.com/kowainik/relude/issues/98): Reexport `Bifoldable` related stuff from `base`.-* [#99](https://github.com/kowainik/relude/issues/99):+- [#99](https://github.com/kowainik/relude/issues/99): Reexport `Bitraversable` related stuff from `base`.-* [#100](https://github.com/kowainik/relude/issues/100):+- [#100](https://github.com/kowainik/relude/issues/100): Add `Relude.Extra.Validation` with `Validation`data type.-* [#89](https://github.com/kowainik/relude/issues/89):+- [#89](https://github.com/kowainik/relude/issues/89): Add `Relude.Extra.Type` module containing a `typeName` function.-* [#92](https://github.com/kowainik/relude/issues/92)+- [#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):+- [#97](https://github.com/kowainik/relude/issues/97): Add `(&&^)` and `(||^)` operators.-* [#81](https://github.com/kowainik/relude/issues/81):+- [#81](https://github.com/kowainik/relude/issues/81): Add `asumMap` to `Foldable` functions.-* [#80](https://github.com/kowainik/relude/issues/80):+- [#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):+- [#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):+- 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):+- [#109](https://github.com/kowainik/relude/issues/109): Use Dhall v3.0.0 for hlint file generation. ## 0.3.0 -* [#41](https://github.com/kowainik/relude/issues/41):+- [#41](https://github.com/kowainik/relude/issues/41): Add `Foldable1`.-* [#63](https://github.com/kowainik/relude/issues/63):+- [#63](https://github.com/kowainik/relude/issues/63): Remove `Print` typeclass. Add `put[L]BS[Ln]` functions. `trace` functions now take `String` as argument instead of `Text`.@@ -417,41 +443,42 @@ **Important:** this is a breaking change. If you used polymorphic `putStrLn` you need to remove type application or switch to one of the monomorphic functions. Also, you can't abstract over `Print` typeclass anymore.-* [#66](https://github.com/kowainik/relude/issues/66):++- [#66](https://github.com/kowainik/relude/issues/66): Export `(>>>)` and `(<<<)` from `Control.Category`.-* [#59](https://github.com/kowainik/relude/issues/59):+- [#59](https://github.com/kowainik/relude/issues/59): Introduce `flap` function and its operator version `??`.-* [#64](https://github.com/kowainik/relude/issues/64):+- [#64](https://github.com/kowainik/relude/issues/64): Improve performance of functions from `Foldable1`. Add `foldl1'` function.-* Reexport `uncons` from `base`.-* Rewrite `die` implementation to use `die` from `base`.-* [#19](https://github.com/kowainik/relude/issues/19):+- Reexport `uncons` from `base`.+- Rewrite `die` implementation to use `die` from `base`.+- [#19](https://github.com/kowainik/relude/issues/19): Rewrite `.hlint.yaml` to Dhall.-* Move `stdin`- and `stdout`-related functions to new module `Relude.Lifted.Terminal`.-* [#67](https://github.com/kowainik/relude/issues/67):+- Move `stdin`- and `stdout`-related functions to new module `Relude.Lifted.Terminal`.+- [#67](https://github.com/kowainik/relude/issues/67): Add HLint rules for `put*` functions.-* [#22](https://github.com/kowainik/relude/issues/22):+- [#22](https://github.com/kowainik/relude/issues/22): `readFile`, `writeFile` and `appendFile` now work with `String`. Add lifted version of `hClose`. Add `readFile`, `writeFile` and `appendFile` alternatives for `Text` and `ByteString`.-* [#61](https://github.com/kowainik/relude/issues/61):+- [#61](https://github.com/kowainik/relude/issues/61): Add `under2` and `underF2` functions to `Relude.Extra.Newtype`.-* [#60](https://github.com/kowainik/relude/issues/60):+- [#60](https://github.com/kowainik/relude/issues/60): Add `hoistMaybe` and `hoistEither` functions. ## 0.2.0 -* [#43](https://github.com/kowainik/relude/issues/43):+- [#43](https://github.com/kowainik/relude/issues/43): Implement `Relude.Extra.Newtype` module.-* [#46](https://github.com/kowainik/relude/issues/46):+- [#46](https://github.com/kowainik/relude/issues/46): Add a function that returns its own name.-* [#48](https://github.com/kowainik/relude/issues/48):+- [#48](https://github.com/kowainik/relude/issues/48): Export `<&>` from `base`. Also reexport `fromLeft` and `fromRight` from `base` where possible.-* [#49](https://github.com/kowainik/relude/issues/49):+- [#49](https://github.com/kowainik/relude/issues/49): Speed up and refactor property tests.-* [#54](https://github.com/kowainik/relude/issues/54):+- [#54](https://github.com/kowainik/relude/issues/54): Improve documentation. Add more examples to documentation and more tests. Reexport `withReader` and `withReaderT`.@@ -460,48 +487,48 @@ ## 0.1.1 -* [#44](https://github.com/kowainik/relude/issues/44):+- [#44](https://github.com/kowainik/relude/issues/44): Implement parser deriviation from pretty-printers. ## 0.1.0 -* [#7](https://github.com/kowainik/relude/issues/7):+- [#7](https://github.com/kowainik/relude/issues/7): Remove `Container.Class.Container`. Export `Foldable`.-* [#2](https://github.com/kowainik/relude/issues/2):+- [#2](https://github.com/kowainik/relude/issues/2): Remove `microlens` from dependencies.-* [#10](https://github.com/kowainik/relude/issues/10):+- [#10](https://github.com/kowainik/relude/issues/10): Remove `VarArg` module.-* [#9](https://github.com/kowainik/relude/issues/9):+- [#9](https://github.com/kowainik/relude/issues/9): Remove `safe-exceptions` from dependencies. Reexport `Exception` and `SomeException` from `Control.Exception` instead.-* [#11](https://github.com/kowainik/relude/issues/11):+- [#11](https://github.com/kowainik/relude/issues/11): Remove `TypeOps` module and `type-operators` dependency.-* [#13](https://github.com/kowainik/relude/issues/13):+- [#13](https://github.com/kowainik/relude/issues/13): Remove `list`, `getContents`, `interact`, `getArgs`, `note` functions. Remove `Lifted.ST` module. Rename `Lifted.Env` to `Lifted.Exit`.-* [#16](https://github.com/kowainik/relude/issues/16):+- [#16](https://github.com/kowainik/relude/issues/16): Rename `whenLeft`, `whenRight`, `whenLeftM`, `whenRightM` to `whenLeft_` and `whenRight_`, `whenLeftM_` and `whenRightM_`. Add `whenLeft`, `whenRight`, `whenLeftM`, `whenRightM` which return the value.-* [#18](https://github.com/kowainik/relude/issues/18):+- [#18](https://github.com/kowainik/relude/issues/18): Add `LazyStrict` type class for conversions.-* `map` is not `fmap` anymore. Reexport `map` from `Data.List`-* [#12](https://github.com/kowainik/relude/issues/12):+- `map` is not `fmap` anymore. Reexport `map` from `Data.List`+- [#12](https://github.com/kowainik/relude/issues/12): Remove `liquid-haskell` support.-* [#20](https://github.com/kowainik/relude/issues/20):+- [#20](https://github.com/kowainik/relude/issues/20): Add `viaNonEmpty` function.-* [#21](https://github.com/kowainik/relude/issues/21):+- [#21](https://github.com/kowainik/relude/issues/21): Add `MonadFail` instance for `Either`.-* [#17](https://github.com/kowainik/relude/issues/17):+- [#17](https://github.com/kowainik/relude/issues/17): Add `foldMapA` and `foldMapM` functions.-* [#4](https://github.com/kowainik/relude/issues/4):+- [#4](https://github.com/kowainik/relude/issues/4): Rename package to `Relude`.-* [#14](https://github.com/kowainik/relude/issues/14):+- [#14](https://github.com/kowainik/relude/issues/14): Add `Relude.Extra.*` modules which are not exported by default but have useful functions.-* [#8](https://github.com/kowainik/relude/issues/8):+- [#8](https://github.com/kowainik/relude/issues/8): Introduce `StaticMap` and `DynamicMap` type classes as universal interface for Map-like structures.
README.md view
@@ -32,28 +32,29 @@ `relude` strives to encourage best-practices and reduce the chances of introducing a bug. - | __Partial__ | __Total__ |- |---------------------------------|--------------------------------------------|- | `head :: [a] -> a` | `head :: NonEmpty a -> a` |- | `tail :: [a] -> [a]` | `tail :: NonEmpty a -> [a]` |- | `read :: Read a => String -> a` | `readMaybe :: Read a => String -> Maybe a` |- | `fromJust :: Maybe a -> a` | `fromMaybe :: a -> Maybe a -> a` |+| **Partial** | **Total** |+| ------------------------------- | ------------------------------------------ |+| `head :: [a] -> a` | `head :: NonEmpty a -> a` |+| `tail :: [a] -> [a]` | `tail :: NonEmpty a -> [a]` |+| `read :: Read a => String -> a` | `readMaybe :: Read a => String -> Maybe a` |+| `fromJust :: Maybe a -> a` | `fromMaybe :: a -> Maybe a -> a` | -3. **Type-safety**. We use the *"make invalid states unrepresentable"* motto as one+3. **Type-safety**. We use the _"make invalid states unrepresentable"_ motto as one of our guiding principles. If it is possible, we express this concept through the types. - _Example:_ Here the function's name type and actions are aligned with each other+ _Example:_ Here the function's name type and actions are aligned with each other - ```haskell- whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()- ```- While in here, the type could represent an unreachable state:+ ```haskell+ whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()+ ``` - ```haskell- whenNotNull :: Applicative f => [a] -> ([a] -> f ()) -> f ()- ```+ While in here, the type could represent an unreachable state: + ```haskell+ whenNotNull :: Applicative f => [a] -> ([a] -> f ()) -> f ()+ ```+ 4. **Performance.** We prefer `Text` over [`String`](https://www.reddit.com/r/haskell/comments/29jw0s/whats_wrong_with_string/), use space-leaks-free functions (e.g. our custom performant `sum` and `product`), introduce `{-# INLINE #-}` and `{-# SPECIALIZE #-}` pragmas where@@ -70,20 +71,21 @@ types and functions into scope, and make available functions easier to use. Some examples of conveniences: - + No need to add `containers`, `unordered-containers`, `text` and+ - No need to add `containers`, `unordered-containers`, `text` and `bytestring` to dependencies in your `.cabal` file to use the main API of these libraries- + No need to import types like `NonEmpty`, `Text`, `Set`, `Reader[T]`, `MVar`, `STM`- + Functions like `liftIO`, `fromMaybe`, `sortWith` are available by default as well- + `IO` actions are lifted to `MonadIO`+ - No need to import types like `NonEmpty`, `Text`, `Set`, `Reader[T]`, `MVar`, `STM`+ - Functions like `liftIO`, `fromMaybe`, `sortWith` are available by default as well+ - `IO` actions are lifted to `MonadIO` 7. **Excellent documentation.**- + Tutorial- + Migration guide from `Prelude`- + Haddock for every function with examples tested by++ - Tutorial+ - Migration guide from `Prelude`+ - Haddock for every function with examples tested by [`doctest`](http://hackage.haskell.org/package/doctest)- + Documentation on [internal module structure](http://hackage.haskell.org/package/relude/docs/Relude.html)- + `relude`-specific [HLint](http://hackage.haskell.org/package/hlint) rules:+ - Documentation on [internal module structure](http://hackage.haskell.org/package/relude/docs/Relude.html)+ - `relude`-specific [HLint](http://hackage.haskell.org/package/hlint) rules: [`.hlint.yaml`](https://github.com/kowainik/relude/blob/main/.hlint.yaml) 8. **User-friendliness.** Anyone should be able to quickly migrate to `relude`. Only@@ -115,12 +117,12 @@ blog post by [Type Classes](https://typeclasses.com/) that highlights `relude`. -* [No implicit Prelude](https://typeclasses.com/ghc/no-implicit-prelude)+- [No implicit Prelude](https://typeclasses.com/ghc/no-implicit-prelude) For guiding development principles behind `relude` and comparison with `base`, check out the following talk: -* [](https://www.youtube.com/watch?v=qwAmiJ5M_zM)+- [](https://www.youtube.com/watch?v=qwAmiJ5M_zM) ## Structure of this tutorial @@ -128,15 +130,15 @@ 1. [When to use an alternative prelude?](#when-to-use-an-alternative-prelude) 2. [Get started](#get-started)- * [Mixins](#mixins)- * [base-noprelude](#base-noprelude)- * [NoImplicitPrelude](#NoImplicitPrelude)+ - [Mixins](#mixins)+ - [NoImplicitPrelude](#noimplicitprelude)+ - [base-noprelude (not recommended)](#base-noprelude) 3. [Difference from Prelude](#difference-from-prelude) 4. [Reexports](#reexports) 5. [What's new?](#whats-new) 6. [Migration guide](#migration-guide) 7. [Comparison with other alternative preludes](#comparison-with-other-alternative-preludes)- * [Relude vs Protolude](#relude-vs-protolude)+ - [Relude vs Protolude](#relude-vs-protolude) 8. [For developers](#for-developers) This is neither a tutorial on _Haskell Standard Library_ nor a tutorial on each@@ -157,13 +159,13 @@ Replacing default `Prelude` from `base` has the following _disadvantages_: -1. Increased entry threshold: you need to *learn* a different standard library.- + `relude` tries to lower this threshold as much as possible: it comes with- the excellent documentation, no custom abstractions, and behavior is- changed only for a small subset of functions.+1. Increased entry threshold: you need to _learn_ a different standard library.+ - `relude` tries to lower this threshold as much as possible: it comes with+ the excellent documentation, no custom abstractions, and behavior is+ changed only for a small subset of functions. 2. Extra dependencies: adding more libraries to dependencies increases build times and maintenance burden.- + `relude` depends only on the boot libraries (almost) which results in small+ - `relude` depends only on the boot libraries (almost) which results in small build time, follows [PVP](https://pvp.haskell.org/) and cares about backwards compatibility. @@ -279,10 +281,40 @@ > If having `stack repl` crucial for your workflow, see the following options of > how to use Relude in your project. +### NoImplicitPrelude++[[Back to the Table of Contents] ↑](#structure-of-this-tutorial)++For this option, you need to disable the default `Prelude` module first.+To disable the built-in prelude on module basis, you can add the following+pragma at the top of your file:++```haskell+{-# LANGUAGE NoImplicitPrelude #-}+```++if you want to disable the default `Prelude` for every module by default, you+can specify this directly in your project `.cabal` file:++```haskell+default-extensions: NoImplicitPrelude+```++Then you need to add `relude` as a dependency of your project.++After doing all above, you can now use `Relude` in any module of your project by+adding a single import:++```haskell+import Relude+```+ ### base-noprelude [[Back to the Table of Contents] ↑](#structure-of-this-tutorial) +:warning: _This strategy is not reccommended. The package `base-noprelude` is currently not being maintained and its use is likely to cause issues with newer versions of ghc and libraries._+ Alternatively, you can use the `base-noprelude` trick to enable alternative preludes. This approach can be helpful if you want to have your own `Prelude` module with some custom functions, not provided by@@ -293,6 +325,7 @@ 2. Add the `relude` dependency to your `.cabal` file. 3. Create the file called `Prelude.hs` in your source directory with the following content:+ ```haskell module Prelude ( module Relude@@ -300,6 +333,7 @@ import Relude ```+ 4. Add this module to `exposed-modules` in your `.cabal` file: ```cabal exposed-modules: Prelude@@ -313,59 +347,31 @@ you don't need to import module manually inside each file and enable the `NoImplicitPrelude` extension. -### NoImplicitPrelude--[[Back to the Table of Contents] ↑](#structure-of-this-tutorial)--For this option, you need to disable the default `Prelude` module first.-To disable the built-in prelude on module basis, you can add the following-pragma at the top of your file:--```haskell-{-# LANGUAGE NoImplicitPrelude #-}-```--if you want to disable the default `Prelude` for every module by default, you-can specify this directly in your project `.cabal` file:--```haskell-default-extensions: NoImplicitPrelude-```--Then you need to add `relude` as a dependency of your project.--After doing all above, you can now use `Relude` in any module of your project by-adding a single import:--```haskell-import Relude-```- ## Difference from Prelude [[Back to the Table of Contents] ↑](#structure-of-this-tutorial) Main differences from `Prelude` can be grouped into the following categories: -* Changed behavior of common functions- + `head`, `tail`, `last`, `init` work with `NonEmpty a` instead of `[a]`.+- Changed behavior of common functions+ - `head`, `tail`, `last`, `init` work with `NonEmpty a` instead of `[a]`. * `lines`, `unlines`, `words`, `unwords` work with `Text` instead of `String`.- + `show` is polymorphic over the return type.- + Functions `sum` and `product` are strict now, which makes them more efficient.- + You can't call `elem` and `notElem` functions over `Set` and `HashSet`.+ - `show` is polymorphic over the return type.+ - Functions `sum` and `product` are strict now, which makes them more efficient.+ - You can't call `elem` and `notElem` functions over `Set` and `HashSet`. These functions are forbidden for these two types due to performance reasons.- + `error` takes `Text`.- + `undefined` triggers a compiler warning, because you probably don't want to+ - `error` takes `Text`.+ - `undefined` triggers a compiler warning, because you probably don't want to leave `undefined` in your code. Either use `throwIO`, `Except`, `error` or `bug`.-* Not reexported- + `read`- + `lookup` for lists- + `log`-* Completely new functions are brought into scope- + See the [What's new?](#whats-new) section for a detailed overview.-* New reexports- + See the [Reexports](#reexports) section for a detailed overview.+- Not reexported+ - `read`+ - `lookup` for lists+ - `log`+- Completely new functions are brought into scope+ - See the [What's new?](#whats-new) section for a detailed overview.+- New reexports+ - See the [Reexports](#reexports) section for a detailed overview. ## Reexports @@ -373,17 +379,17 @@ `relude` reexports some parts of the following libraries: -* [`base`](http://hackage.haskell.org/package/base)-* [`bytestring`](http://hackage.haskell.org/package/bytestring)-* [`containers`](http://hackage.haskell.org/package/containers)-* [`deepseq`](http://hackage.haskell.org/package/deepseq)-* [`ghc-prim`](http://hackage.haskell.org/package/ghc-prim)-* [`hashable`](http://hackage.haskell.org/package/hashable)-* [`mtl`](http://hackage.haskell.org/package/mtl)-* [`stm`](http://hackage.haskell.org/package/stm)-* [`text`](http://hackage.haskell.org/package/text)-* [`transformers`](http://hackage.haskell.org/package/transformers)-* [`unordered-containers`](http://hackage.haskell.org/package/unordered-containers)+- [`base`](http://hackage.haskell.org/package/base)+- [`bytestring`](http://hackage.haskell.org/package/bytestring)+- [`containers`](http://hackage.haskell.org/package/containers)+- [`deepseq`](http://hackage.haskell.org/package/deepseq)+- [`ghc-prim`](http://hackage.haskell.org/package/ghc-prim)+- [`hashable`](http://hackage.haskell.org/package/hashable)+- [`mtl`](http://hackage.haskell.org/package/mtl)+- [`stm`](http://hackage.haskell.org/package/stm)+- [`text`](http://hackage.haskell.org/package/text)+- [`transformers`](http://hackage.haskell.org/package/transformers)+- [`unordered-containers`](http://hackage.haskell.org/package/unordered-containers) If you want to clean up your imports after switching to `relude`, you can use the `relude`-specific@@ -395,14 +401,14 @@ Multiple sorting functions are available for different use-cases: - + `sortBy :: (a -> a -> Ordering) -> [a] -> [a]`: sorts a list using given- custom comparator.- + `sortWith :: Ord b => (a -> b) -> [a] -> [a]`: sorts a list based on some- property of its elements.- + `sortOn :: Ord b => (a -> b) -> [a] -> [a]`: similar to `sortWith`, but more- time-efficient if function is calculated slowly (though less- space-efficient). So you should write `sortOn length` (would sort elements- by length) but `sortWith fst` (would sort list of pairs by first element).+- `sortBy :: (a -> a -> Ordering) -> [a] -> [a]`: sorts a list using given+ custom comparator.+- `sortWith :: Ord b => (a -> b) -> [a] -> [a]`: sorts a list based on some+ property of its elements.+- `sortOn :: Ord b => (a -> b) -> [a] -> [a]`: similar to `sortWith`, but more+ time-efficient if function is calculated slowly (though less+ space-efficient). So you should write `sortOn length` (would sort elements+ by length) but `sortWith fst` (would sort list of pairs by first element). `readMaybe` and `readEither` are similar to `read` but unlike it, they are total and return either `Maybe` or `Either` with a parse error.@@ -410,9 +416,9 @@ `(&)` is the reverse application. The following three expressions are semantically equivalent: -* `g (f x)`-* `g $ f $ x`-* `x & f & g`+- `g (f x)`+- `g $ f $ x`+- `x & f & g` Some generally useful modules from `base` package are exported, e.g. `Control.Applicative`, `Data.Traversable`, `Data.Monoid`, `Data.List`,@@ -424,10 +430,10 @@ [`Bifunctor`](http://hackage.haskell.org/package/base/docs/Data-Bifunctor.html) type class with useful instances is exported. -* `first` and `second` functions apply a function to the first and+- `first` and `second` functions apply a function to the first and second part of a `Bifunctor` (`fst` and `snd` for tuples, `Left` and `Right` for `Either`).-* `bimap` takes two functions and applies them to the first and second parts respectively.+- `bimap` takes two functions and applies them to the first and second parts respectively. `trace`, `traceM`, `traceShow`, etc. are available by default. However, GHC will warn you if you accidentally leave them in code. Same goes for the `undefined`@@ -447,9 +453,9 @@ The following types from these two packages are exported: -* Maps: strict versions of `Map`, `HashMap`, `IntMap`.-* Sets: `Set`, `HashSet`, `IntSet`.-* Sequences: `Seq`.+- Maps: strict versions of `Map`, `HashMap`, `IntMap`.+- Sets: `Set`, `HashSet`, `IntSet`.+- Sequences: `Seq`. ### text & bytestring @@ -473,8 +479,8 @@ The following parts of these two libraries are exported: -* Transformers: `State[T]`, `Reader[T]`, `ExceptT`, `MaybeT`.-* Classes: `MonadReader`, `MonadState`.+- Transformers: `State[T]`, `Reader[T]`, `ExceptT`, `MaybeT`.+- Classes: `MonadReader`, `MonadState`. ### Deepseq @@ -493,7 +499,8 @@ ### Available by default -* Safe analogue for the list functions:+- Safe analogue for the list functions:+ ```haskell head :: NonEmpty a -> a -- the first element of the list tail :: NonEmpty a -> [a] -- the list without the first element@@ -512,18 +519,18 @@ Nothing ``` -* `uncons` splits a list at the first element.-* `ordNub` and `sortNub` are _O(n log n)_ versions of `nub` (which is quadratic),+- `uncons` splits a list at the first element.+- `ordNub` and `sortNub` are _O(n log n)_ versions of `nub` (which is quadratic), also, `hashNub` and `unstableNub` are almost _O(n)_ versions of `nub`, and `intNub` for fast `Int`s nub.-* `whenM`, `unlessM`, `ifM`, `guardM` — monadic guard combinators, that work+- `whenM`, `unlessM`, `ifM`, `guardM` — monadic guard combinators, that work with any `Monad`, e.g. `whenM (doesFileExist "foo")`.-* General fold functions:+- General fold functions: ```haskell foldMapA :: (Monoid b, Applicative m, Foldable f) => (a -> m b) -> f a -> m b foldMapM :: (Monoid b, Monad m, Foldable f) => (a -> m b) -> f a -> m b ```-* `when(Just|Nothing|Left|Right|NotEmpty)[M][_]` functions that+- `when(Just|Nothing|Left|Right|NotEmpty)[M][_]` functions that let you conditionally execute something. **Before:**@@ -541,23 +548,23 @@ f x ``` -* `for_` and `forM_` for loops.+- `for_` and `forM_` for loops. ```haskell for_ files $ \file -> do ... ``` -* `andM`, `allM`, `anyM`, `orM` are monadic versions of the corresponding+- `andM`, `allM`, `anyM`, `orM` are monadic versions of the corresponding functions from `base`.-* Conversions between `Either` and `Maybe`, e.g. `rightToMaybe` and `maybeToLeft`+- Conversions between `Either` and `Maybe`, e.g. `rightToMaybe` and `maybeToLeft` with clear semantics.-* `using(Reader|State)[T]` functions as aliases for `flip run(Reader|State)[T]`.-* [`One` type class](http://hackage.haskell.org/package/relude/docs/Relude-Container-One.html)+- `using(Reader|State)[T]` functions as aliases for `flip run(Reader|State)[T]`.+- [`One` type class](http://hackage.haskell.org/package/relude/docs/Relude-Container-One.html) for creating singleton containers (even monomorphic ones like `Text`).-* `evaluateWHNF` and `evaluateNF` functions as clearer and lifted aliases for+- `evaluateWHNF` and `evaluateNF` functions as clearer and lifted aliases for `evaluate` and `evaluate . force`.-* `MonadFail` instance for `Either`.+- `MonadFail` instance for `Either`. ### Extra bonuses @@ -567,13 +574,15 @@ These extra modules include the following functionality: -* Convenient functions to work with `(Bounded a, Enum a)` types:+- Convenient functions to work with `(Bounded a, Enum a)` types:+ 1. `universe :: (Bounded a, Enum a) => [a]`: get all values of the type. ```haskell ghci> universe @Bool [True,False] ```+ 2. `inverseMap :: (Bounded a, Enum a, Ord k) => (a -> k) -> k -> Maybe a`: convert functions like `show` to parsers: @@ -582,7 +591,7 @@ readMyEnums = inverseMap myShow ``` -* Nice helpers to deal with `newtype`s in a more pleasant way:+- Nice helpers to deal with `newtype`s in a more pleasant way: ```haskell ghci> newtype Foo = Foo Bool deriving Show@@ -590,7 +599,7 @@ Foo False ``` -* Functions to operate with `CallStack`:+- Functions to operate with `CallStack`: ```haskell ghci> foo :: HasCallStack => String; foo = ownName@@ -598,11 +607,11 @@ "foo" ``` -* `Foldable1` typeclass that contains generalized interface for folding+- `Foldable1` typeclass that contains generalized interface for folding non-empty structures like `NonEmpty`.-* [`StaticMap` and `DynamicMap` type classes](https://github.com/kowainik/relude/blob/main/src/Relude/Extra/Map.hs) as a+- [`StaticMap` and `DynamicMap` type classes](https://github.com/kowainik/relude/blob/main/src/Relude/Extra/Map.hs) as a general interface for `Map`-like data structures.-* And much more!+- And much more! Explore `Extra` modules: [`Relude.Extra`](http://hackage.haskell.org/package/relude/docs/Relude-Extra.html) @@ -614,7 +623,7 @@ to the `relude` library. In order to replace the default `Prelude` with `relude` you should start with-instructions provided in the [_Get Started_](#get-started) section.+instructions provided in the [_Get Started_](#get-started) section. ### Code changes @@ -626,51 +635,53 @@ 1. Change `[a]` to `NonEmpty a` where it makes sense. 2. Use functions which return `Maybe`. There is the `viaNonEmpty` function for this. And you can use it like `viaNonEmpty last l`.- + `tail` is `drop 1`. It's almost never a good idea to use `tail` from `Prelude`.+ - `tail` is `drop 1`. It's almost never a good idea to use `tail` from `Prelude`. 3. Add `import qualified Relude.Unsafe as Unsafe` and replace the function with its qualified usage: `Unsafe.head`. 3. If you use `fromJust` or `!!` you should import them from `import qualified Relude.Unsafe as Unsafe`. 4. If you use `foldr` or `forM_` or similar for something like `Maybe a` or `Either a b` it is recommended to replace usages of such functions with the monomorhpic alternatives:- * `Maybe`- + `(?:) :: Maybe a -> a -> a`- + `fromMaybe :: a -> Maybe a -> a`- + `maybeToList :: Maybe a -> [a]`- + `maybeToMonoid :: Monoid m => Maybe m -> m`- + `maybe :: b -> (a -> b) -> Maybe a -> b`- + `whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()`- + `whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()` - * `Either`- + `fromLeft :: a -> Either a b -> a`- + `fromRight :: b -> Either a b -> b`- + `either :: (a -> c) -> (b -> c) -> Either a b -> c`- + `whenRight_ :: Applicative f => Either l r -> (r -> f ()) -> f ()`- + `whenRightM_ :: Monad m => m (Either l r) -> (r -> m ()) -> m ()`+ - `Maybe` + - `(?:) :: Maybe a -> a -> a`+ - `fromMaybe :: a -> Maybe a -> a`+ - `maybeToList :: Maybe a -> [a]`+ - `maybeToMonoid :: Monoid m => Maybe m -> m`+ - `maybe :: b -> (a -> b) -> Maybe a -> b`+ - `whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()`+ - `whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()`++ - `Either`+ - `fromLeft :: a -> Either a b -> a`+ - `fromRight :: b -> Either a b -> b`+ - `either :: (a -> c) -> (b -> c) -> Either a b -> c`+ - `whenRight_ :: Applicative f => Either l r -> (r -> f ()) -> f ()`+ - `whenRightM_ :: Monad m => m (Either l r) -> (r -> m ()) -> m ()`+ 5. Replace the `String` type with more efficient and suitable ones (e.g. `Text`):- + Replace `(++)` with `(<>)` for `String`-like types.- + 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. + - Replace `(++)` with `(<>)` for `String`-like types.+ - 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. Since `show` doesn't come from `Show` anymore, you need to import the- `Text.Show` module if you want to implement `Show` instance manually. This can be done in the following way:+ `Text.Show` module if you want to implement `Show` instance manually. This can be done in the following way: - ```haskell- import qualified Text.Show+```haskell+import qualified Text.Show - data MyType = ...+data MyType = ... - instance Show MyType where- show :: MyType -> String- show = ...- ```+instance Show MyType where+ show :: MyType -> String+ show = ...+``` 7. 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,@@ -693,7 +704,7 @@ See an example of this feature described in the following blog post about Travis CI settings: -* [Kodimensional: Dead simple Haskell Travis settings for cabal and stack](https://kodimensional.dev/posts/2019-02-25-haskell-travis#customization-hlint)+- [Kodimensional: Dead simple Haskell Travis settings for cabal and stack](https://kodimensional.dev/posts/2019-02-25-haskell-travis#customization-hlint) ## Comparison with other alternative preludes @@ -728,14 +739,14 @@ is scary in some places as a consequence and it is more difficult to add, remove or change things there. 5. `relude` has much better documentation:- * [High-level overview of internal module structure](http://hackage.haskell.org/package/relude/docs/Relude.html)- * 100% Haddock coverage- * Every function has usage examples and all examples are tested with- `doctest` (which also sometimes hard to do due to the 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.+ - [High-level overview of internal module structure](http://hackage.haskell.org/package/relude/docs/Relude.html)+ - 100% Haddock coverage+ - Every function has usage examples and all examples are tested with+ `doctest` (which also sometimes hard to do due to the 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. 6. `relude` has fewer dependencies and is slightly lighter because of that but still is very powerful and useful. 7. `relude` is opt-in oriented and has a notion of `Extra.*` modules that are@@ -777,7 +788,7 @@ 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)+- [Dhall To HLint](https://kowainik.github.io/posts/2018-09-09-dhall-to-hlint) ### Producing dependency graph
relude.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: relude-version: 1.2.0.0+version: 1.2.1.0 synopsis: Safe, performant, user-friendly and lightweight Haskell Standard Library description: @__relude__@ is an alternative prelude library. If you find the default@@ -96,8 +96,9 @@ GHC == 8.8.4 GHC == 8.10.7 GHC == 9.0.2- GHC == 9.2.7- GHC == 9.4.4+ GHC == 9.2.8+ GHC == 9.4.7+ GHC == 9.6.3 source-repository head@@ -228,15 +229,15 @@ , Data.ByteString.Short - build-depends: base >= 4.11 && < 4.18- , bytestring >= 0.10 && < 0.12- , containers >= 0.5.10 && < 0.7- , deepseq ^>= 1.4- , ghc-prim >= 0.5.0.0 && < 0.10+ build-depends: base >= 4.11 && < 4.19+ , bytestring >= 0.10 && < 0.13+ , containers >= 0.5.10 && < 0.8+ , deepseq >= 1.4 && < 1.6+ , ghc-prim >= 0.5.0.0 && < 0.11 , hashable >= 1.2 && < 1.5 , mtl >= 2.2 && < 2.4 , stm >= 2.4 && < 2.6- , text >= 1.2 && < 2.1+ , text >= 1.2 && < 2.2 , transformers >= 0.5 && < 0.7 , unordered-containers >= 0.2.7 && < 0.3 @@ -255,7 +256,7 @@ , bytestring , containers , text- , hedgehog >= 1.0 && < 1.3+ , hedgehog >= 1.0 && < 1.4 ghc-options: -threaded @@ -266,7 +267,7 @@ main-is: Doctest.hs build-depends: relude- , doctest >= 0.20 && < 0.22+ , doctest >= 0.20 && < 0.23 , Glob ghc-options: -threaded
src/Relude/Debug.hs view
@@ -1,4 +1,9 @@ {-# LANGUAGE CPP #-}++#if __GLASGOW_HASKELL__ >= 902+{-# OPTIONS_GHC -Wno-operator-whitespace #-}+#endif+ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveDataTypeable #-}@@ -9,7 +14,9 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeFamilies #-}+#if ( __GLASGOW_HASKELL__ < 906 ) {-# LANGUAGE TypeInType #-}+#endif {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} @@ -255,13 +262,13 @@ >>> error "oops" *** Exception: oops CallStack (from HasCallStack):- error, called at src\Relude\Debug.hs:289:11 in ...+ error, called at src\Relude\Debug.hs:296:11 in ... ... #else >>> error "oops" *** Exception: oops CallStack (from HasCallStack):- error, called at src/Relude/Debug.hs:289:11 in ...+ error, called at src/Relude/Debug.hs:296:11 in ... ... #endif
src/Relude/Extra/Foldable1.hs view
@@ -1,5 +1,11 @@ {-# OPTIONS_GHC -Wno-redundant-constraints #-} +{-# LANGUAGE CPP #-}++#if __GLASGOW_HASKELL__ >= 902+{-# OPTIONS_GHC -Wno-operator-whitespace #-}+#endif+ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE Safe #-}@@ -89,7 +95,7 @@ 2 :| [] -} toNonEmpty :: f a -> NonEmpty a- toNonEmpty = foldMap1 (:|[])+ toNonEmpty = foldMap1 (:| []) {- | The first element of a non-empty data structure. @@ -211,7 +217,7 @@ {-# INLINE fold1 #-} toNonEmpty :: Identity a -> NonEmpty a- toNonEmpty = (:|[]) . coerce+ toNonEmpty = (:| []) . coerce {-# INLINE toNonEmpty #-} head1 :: Identity a -> a@@ -252,7 +258,7 @@ {-# INLINE fold1 #-} toNonEmpty :: (c, a) -> NonEmpty a- toNonEmpty (_, y) = (y :| [])+ toNonEmpty (_, y) = y :| [] {-# INLINE toNonEmpty #-} head1, last1 :: (c, a) -> a@@ -406,7 +412,7 @@ @since 1.0.0.0 -} average1 :: forall a f . (Foldable1 f, Fractional a) => f a -> a-average1 = uncurry (/) . foldl' (\(!total, !count) x -> (total + x, count + 1)) (0,0)+average1 = uncurry (/) . foldl' (\(!total, !count) x -> (total + x, count + 1)) (0, 0) {-# INLINE average1 #-} {-
src/Relude/Extra/Type.hs view
@@ -35,8 +35,14 @@ import Type.Reflection (typeRep) +#if ( __GLASGOW_HASKELL__ >= 906 ) -- $setup -- >>> :set -XAllowAmbiguousTypes -XDataKinds -XExplicitNamespaces -XPolyKinds -XTypeFamilies -XTypeOperators -XUndecidableInstances+-- >>> :set -fprint-redundant-promotion-ticks+#else+-- $setup+-- >>> :set -XAllowAmbiguousTypes -XDataKinds -XExplicitNamespaces -XPolyKinds -XTypeFamilies -XTypeOperators -XUndecidableInstances+#endif {- | Gets a string representation of a type.
src/Relude/Foldable/Fold.hs view
@@ -1,5 +1,11 @@ {-# OPTIONS_GHC -Wno-redundant-constraints #-} +{-# LANGUAGE CPP #-}++#if __GLASGOW_HASKELL__ >= 902+{-# OPTIONS_GHC -Wno-operator-whitespace #-}+#endif+ {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE Safe #-}
src/Relude/List/NonEmpty.hs view
@@ -1,4 +1,9 @@ {-# LANGUAGE CPP #-}++#if __GLASGOW_HASKELL__ >= 902+{-# OPTIONS_GHC -Wno-operator-whitespace #-}+#endif+ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE Safe #-}
src/Relude/String/Conversion.hs view
@@ -1,4 +1,9 @@ {-# LANGUAGE CPP #-}++#if __GLASGOW_HASKELL__ >= 902+{-# OPTIONS_GHC -Wno-operator-whitespace #-}+#endif+ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-}@@ -102,12 +107,15 @@ "\65533\65533\1090\1072\1082" #endif -#if MIN_VERSION_text(2,0,0)+#if MIN_VERSION_text(2,0,2) >>> decodeUtf8Strict @Text @ByteString "\208\208\176\209\130\208\176\208\186"- Left Cannot decode byte '\xd0': Data.Text.Internal.Encoding: Invalid UTF-8 stream+ Left Cannot decode byte '\xd0': ...: Invalid UTF-8 stream+#elif MIN_VERSION_text(2,0,0)+ >>> decodeUtf8Strict @Text @ByteString "\208\208\176\209\130\208\176\208\186"+ Left Cannot decode byte '\xd0': ...: Invalid UTF-8 stream #else >>> decodeUtf8Strict @Text @ByteString "\208\208\176\209\130\208\176\208\186"- Left Cannot decode byte '\xd0': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream+ Left Cannot decode byte '\xd0': ...: Invalid UTF-8 stream #endif -} decodeUtf8Strict :: b -> Either T.UnicodeException a
src/Relude/String/Reexport.hs view
@@ -1,4 +1,9 @@ {-# LANGUAGE CPP #-}++#if __GLASGOW_HASKELL__ >= 902+{-# OPTIONS_GHC -Wno-operator-whitespace #-}+#endif+ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-}