diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..4435abb --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,12 @@ +**Description of the change** + +Clearly and concisely describe the purpose of the pull request. If this PR relates to an existing issue or change proposal, please link to it. Include any other background context that would help reviewers understand the motivation for this PR. + +--- + +**Checklist:** + +- [ ] Added the change to the changelog's "Unreleased" section with a reference to this PR (e.g. "- Made a change (#0000)") +- [ ] Linked any existing issues or proposals that this pull request should close +- [ ] Updated or added relevant documentation +- [ ] Added a test for the contribution (if applicable) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2972ba..c69237a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,10 @@ name: CI -on: push +on: + push: + branches: [master] + pull_request: + branches: [master] jobs: build: @@ -10,11 +14,11 @@ jobs: - uses: purescript-contrib/setup-purescript@main with: - purescript: "0.14.0-rc3" + purescript: "unstable" - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: - node-version: "12" + node-version: "14.x" - name: Install dependencies run: | diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..73022e2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,155 @@ +# Changelog + +Notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +Breaking changes: + +New features: + +Bugfixes: + +Other improvements: + +## [v6.1.0](https://github.com/purescript/purescript-either/releases/tag/v6.1.0) - 2022-05-16 + +New features: +- Add `blush` which is a left-biased `hush`, thus turns `Right`s into `Nothing`s but `Left`s into `Just`s (#69 by @i-am-the-slime). + +## [v6.0.0](https://github.com/purescript/purescript-either/releases/tag/v6.0.0) - 2022-04-27 + +Breaking changes: +- Update project and deps to PureScript v0.15.0 (#66 by @JordanMartinez) + +New features: + +Bugfixes: + +Other improvements: + +## [v5.0.0](https://github.com/purescript/purescript-either/releases/tag/v5.0.0) - 2021-02-26 + +Breaking changes: +- Added support for PureScript 0.14 and dropped support for all previous versions (#55) +- Added default parameter to `fromLeft` and `fromRight` and removed `Partial` constraint (#48) + +New features: +- Added `\/` alias for `either` (#51) +- Added lazy versions of `fromRight` and `fromLeft` (#59) +- This package no longer depends on the `purescript-bifunctors` and `purescript-foldable-traversable` packages. Relevant instances have been moved to those packages. (#64) + +Bugfixes: + +Other improvements: +- Migrated CI to GitHub Actions and updated installation instructions to use Spago (#58) +- Added a CHANGELOG.md file and pull request template (#62, #63) +- Corrected docs for `Apply` instance (#49) +- Improved documentation of `Either`s "do notation" (#52) + +## [v4.1.1](https://github.com/purescript/purescript-either/releases/tag/v4.1.1) - 2018-11-30 + +Reordered instance chain for `Inject` so that `inj :: a -> a` succeeds (@hdgarrood) + +## [v4.1.0](https://github.com/purescript/purescript-either/releases/tag/v4.1.0) - 2018-10-28 + +Added `FunctorWithIndex`, `FoldableWithIndex`, `TraversableWithIndex` instances (@MonoidMusician) + +## [v4.0.0](https://github.com/purescript/purescript-either/releases/tag/v4.0.0) - 2018-05-23 + +- Updated for PureScript 0.12 +- Added `\/` type synonym to `Data.Either.Nested` +- Added `Inject` class for injecting values into/projecting values out of nested `Eithers` + +## [v3.2.0](https://github.com/purescript/purescript-either/releases/tag/v3.2.0) - 2018-04-15 + +- Added `note'` (lazy `note`) (@matthewleon) + +## [v3.1.0](https://github.com/purescript/purescript-either/releases/tag/v3.1.0) - 2017-06-23 + +- Added `note` and `hush` functions (@kRITZCREEK) + +## [v3.0.0](https://github.com/purescript/purescript-either/releases/tag/v3.0.0) - 2017-03-26 + +- Updated for PureScript 0.11 + +## [v2.2.1](https://github.com/purescript/purescript-either/releases/tag/v2.2.1) - 2017-03-05 + +- Fix lower bound of prelude dependency (@passy) + +## [v2.2.0](https://github.com/purescript/purescript-either/releases/tag/v2.2.0) - 2017-03-02 + +- Added `Eq1` and `Ord1` instances + +## [v2.1.0](https://github.com/purescript/purescript-either/releases/tag/v2.1.0) - 2016-12-24 + +Add `choose` function (@tmcgilchrist) + +## [v2.0.0](https://github.com/purescript/purescript-either/releases/tag/v2.0.0) - 2016-10-03 + +- Updated dependencies +- The `Nested` module has been reworked for "open" nesting #20 (@natefaubion) + +## [v1.0.0](https://github.com/purescript/purescript-either/releases/tag/v1.0.0) - 2016-06-01 + +This release is intended for the PureScript 0.9.1 compiler and newer. + +**Note**: The v1.0.0 tag is not meant to indicate the library is “finished”, the core libraries are all being bumped to this for the 0.9 compiler release so as to use semver more correctly. + +## [v1.0.0-rc.1](https://github.com/purescript/purescript-either/releases/tag/v1.0.0-rc.1) - 2016-03-13 + +- Release candidate for the psc 0.8+ core libraries + +## [v0.2.3](https://github.com/purescript/purescript-either/releases/tag/v0.2.3) - 2015-09-26 + +Fixed error message (@zudov) + +## [v0.2.2](https://github.com/purescript/purescript-either/releases/tag/v0.2.2) - 2015-08-14 + +- Added `Semiring` and `Semigroup` instances (@anttih) + +## [v0.2.1](https://github.com/purescript/purescript-either/releases/tag/v0.2.1) - 2015-08-13 + +- Fixed warnings about partial functions + +## [v0.2.0](https://github.com/purescript/purescript-either/releases/tag/v0.2.0) - 2015-06-30 + +This release works with versions 0.7.\* of the PureScript compiler. It will not work with older versions. If you are using an older version, you should require an older, compatible version of this library. + +## [v0.2.0-rc.1](https://github.com/purescript/purescript-either/releases/tag/v0.2.0-rc.1) - 2015-06-06 + +Initial release candidate of the library intended for the 0.7 compiler. + +## [v0.1.8](https://github.com/purescript/purescript-either/releases/tag/v0.1.8) - 2015-03-25 + +More helper functions for nested sums (@jdegoes) + +## [v0.1.7](https://github.com/purescript/purescript-either/releases/tag/v0.1.7) - 2015-03-24 + +Reworked nested sums (@jdegoes) + +## [v0.1.6](https://github.com/purescript/purescript-either/releases/tag/v0.1.6) - 2015-03-18 + +Add `fromLeft` and `fromRight` (@pseudonom) + +## [v0.1.5](https://github.com/purescript/purescript-either/releases/tag/v0.1.5) - 2015-03-17 + +Update docs + +## [v0.1.4](https://github.com/purescript/purescript-either/releases/tag/v0.1.4) - 2014-11-05 + + + +## [v0.1.3](https://github.com/purescript/purescript-either/releases/tag/v0.1.3) - 2014-08-26 + +Add `Alt` instance + +## [v0.1.2](https://github.com/purescript/purescript-either/releases/tag/v0.1.2) - 2014-05-22 + +- Fixed `show` output (paf31) + +## [v0.1.1](https://github.com/purescript/purescript-either/releases/tag/v0.1.1) - 2014-04-25 + + + +## [v0.1.0](https://github.com/purescript/purescript-either/releases/tag/v0.1.0) - 2014-04-21 diff --git a/README.md b/README.md index 84f8cbd..b361259 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Latest release](http://img.shields.io/github/release/purescript/purescript-either.svg)](https://github.com/purescript/purescript-either/releases) [![Build status](https://github.com/purescript/purescript-either/workflows/CI/badge.svg?branch=master)](https://github.com/purescript/purescript-either/actions?query=workflow%3ACI+branch%3Amaster) +[![Pursuit](https://pursuit.purescript.org/packages/purescript-either/badge)](https://pursuit.purescript.org/packages/purescript-either) The `Either` type provides is used to represent values that can be one of two possibilities. For example, `Either Int Number` can be used in a place where either integers or floating point numbers are acceptable. diff --git a/bower.json b/bower.json index 1702a87..6e9638d 100644 --- a/bower.json +++ b/bower.json @@ -4,7 +4,7 @@ "license": "BSD-3-Clause", "repository": { "type": "git", - "url": "git://github.com/purescript/purescript-either.git" + "url": "https://github.com/purescript/purescript-either.git" }, "ignore": [ "**/.*", @@ -16,16 +16,14 @@ "package.json" ], "dependencies": { - "purescript-bifunctors": "master", - "purescript-control": "master", - "purescript-foldable-traversable": "master", - "purescript-invariant": "master", - "purescript-maybe": "master", - "purescript-prelude": "master" + "purescript-control": "^6.0.0", + "purescript-invariant": "^6.0.0", + "purescript-maybe": "^6.0.0", + "purescript-prelude": "^6.0.0" }, "devDependencies": { - "purescript-assert": "master", - "purescript-console": "master", - "purescript-effect": "master" + "purescript-assert": "^6.0.0", + "purescript-console": "^6.0.0", + "purescript-effect": "^4.0.0" } } diff --git a/package.json b/package.json index 1fac874..c8e10e0 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "test": "pulp test" }, "devDependencies": { - "pulp": "^15.0.0", - "purescript-psa": "^0.8.0", - "rimraf": "^2.6.2" + "pulp": "16.0.0-0", + "purescript-psa": "^0.8.2", + "rimraf": "^3.0.2" } } diff --git a/src/Data/Either.purs b/src/Data/Either.purs index 65cc805..3940d93 100644 --- a/src/Data/Either.purs +++ b/src/Data/Either.purs @@ -4,18 +4,11 @@ import Prelude import Control.Alt (class Alt, (<|>)) import Control.Extend (class Extend) -import Data.Bifoldable (class Bifoldable) -import Data.Bifunctor (class Bifunctor) -import Data.Bitraversable (class Bitraversable) import Data.Eq (class Eq1) -import Data.Foldable (class Foldable) -import Data.FoldableWithIndex (class FoldableWithIndex) import Data.Functor.Invariant (class Invariant, imapF) -import Data.FunctorWithIndex (class FunctorWithIndex) +import Data.Generic.Rep (class Generic) import Data.Maybe (Maybe(..), maybe, maybe') import Data.Ord (class Ord1) -import Data.Traversable (class Traversable) -import Data.TraversableWithIndex (class TraversableWithIndex) -- | The `Either` type is used to represent a choice between two types of value. -- | @@ -37,16 +30,11 @@ data Either a b = Left a | Right b -- | ``` derive instance functorEither :: Functor (Either a) -instance functorWithIndexEither :: FunctorWithIndex Unit (Either a) where - mapWithIndex f = map $ f unit +derive instance genericEither :: Generic (Either a b) _ instance invariantEither :: Invariant (Either a) where imap = imapF -instance bifunctorEither :: Bifunctor Either where - bimap f _ (Left l) = Left (f l) - bimap _ g (Right r) = Right (g r) - -- | The `Apply` instance allows functions contained within a `Right` to -- | transform a value contained within a `Right` using the `(<*>)` operator: -- | @@ -206,46 +194,6 @@ instance boundedEither :: (Bounded a, Bounded b) => Bounded (Either a b) where top = Right top bottom = Left bottom -instance foldableEither :: Foldable (Either a) where - foldr _ z (Left _) = z - foldr f z (Right x) = f x z - foldl _ z (Left _) = z - foldl f z (Right x) = f z x - foldMap f (Left _) = mempty - foldMap f (Right x) = f x - -instance foldableWithIndexEither :: FoldableWithIndex Unit (Either a) where - foldrWithIndex _ z (Left _) = z - foldrWithIndex f z (Right x) = f unit x z - foldlWithIndex _ z (Left _) = z - foldlWithIndex f z (Right x) = f unit z x - foldMapWithIndex f (Left _) = mempty - foldMapWithIndex f (Right x) = f unit x - -instance bifoldableEither :: Bifoldable Either where - bifoldr f _ z (Left a) = f a z - bifoldr _ g z (Right b) = g b z - bifoldl f _ z (Left a) = f z a - bifoldl _ g z (Right b) = g z b - bifoldMap f _ (Left a) = f a - bifoldMap _ g (Right b) = g b - -instance traversableEither :: Traversable (Either a) where - traverse _ (Left x) = pure (Left x) - traverse f (Right x) = Right <$> f x - sequence (Left x) = pure (Left x) - sequence (Right x) = Right <$> x - -instance traversableWithIndexEither :: TraversableWithIndex Unit (Either a) where - traverseWithIndex _ (Left x) = pure (Left x) - traverseWithIndex f (Right x) = Right <$> f unit x - -instance bitraversableEither :: Bitraversable Either where - bitraverse f _ (Left a) = Left <$> f a - bitraverse _ g (Right b) = Right <$> g b - bisequence (Left a) = Left <$> a - bisequence (Right b) = Right <$> b - instance semigroupEither :: (Semigroup b) => Semigroup (Either a b) where append x y = append <$> x <*> y @@ -280,6 +228,15 @@ fromLeft :: forall a b. a -> Either a b -> a fromLeft _ (Left a) = a fromLeft default _ = default +-- | Similar to `fromLeft` but for use in cases where the default value may be +-- | expensive to compute. As PureScript is not lazy, the standard `fromLeft` +-- | has to evaluate the default value before returning the result, +-- | whereas here the value is only computed when the `Either` is known +-- | to be `Right`. +fromLeft' :: forall a b. (Unit -> a) -> Either a b -> a +fromLeft' _ (Left a) = a +fromLeft' default _ = default unit + -- | A function that extracts the value from the `Right` data constructor. -- | The first argument is a default value, which will be returned in the -- | case where a `Left` is passed to `fromRight`. @@ -287,6 +244,15 @@ fromRight :: forall a b. b -> Either a b -> b fromRight _ (Right b) = b fromRight default _ = default +-- | Similar to `fromRight` but for use in cases where the default value may be +-- | expensive to compute. As PureScript is not lazy, the standard `fromRight` +-- | has to evaluate the default value before returning the result, +-- | whereas here the value is only computed when the `Either` is known +-- | to be `Left`. +fromRight' :: forall a b. (Unit -> b) -> Either a b -> b +fromRight' _ (Right b) = b +fromRight' default _ = default unit + -- | Takes a default and a `Maybe` value, if the value is a `Just`, turn it into -- | a `Right`, if the value is a `Nothing` use the provided default as a `Left` -- | @@ -307,7 +273,7 @@ note a = maybe (Left a) Right note' :: forall a b. (Unit -> a) -> Maybe b -> Either a b note' f = maybe' (Left <<< f) Right --- | Turns an `Either` into a `Maybe`, by throwing eventual `Left` values away and converting +-- | Turns an `Either` into a `Maybe`, by throwing potential `Left` values away and converting -- | them into `Nothing`. `Right` values get turned into `Just`s. -- | -- | ```purescript @@ -316,3 +282,13 @@ note' f = maybe' (Left <<< f) Right -- | ``` hush :: forall a b. Either a b -> Maybe b hush = either (const Nothing) Just + +-- | Turns an `Either` into a `Maybe`, by throwing potential `Right` values away and converting +-- | them into `Nothing`. `Left` values get turned into `Just`s. +-- | +-- | ```purescript +-- | blush (Left "ParseError") = Just "Parse Error" +-- | blush (Right 42) = Nothing +-- | ``` +blush :: forall a b. Either a b -> Maybe a +blush = either Just (const Nothing)