├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bower.json ├── package.json └── src ├── Control ├── Biapplicative.purs └── Biapply.purs └── Data ├── Bifunctor.purs └── Bifunctor └── Join.purs /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Description of the change** 2 | 3 | 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. 4 | 5 | --- 6 | 7 | **Checklist:** 8 | 9 | - [ ] Added the change to the changelog's "Unreleased" section with a reference to this PR (e.g. "- Made a change (#0000)") 10 | - [ ] Linked any existing issues or proposals that this pull request should close 11 | - [ ] Updated or added relevant documentation 12 | - [ ] Added a test for the contribution (if applicable) 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - uses: purescript-contrib/setup-purescript@main 16 | with: 17 | purescript: "unstable" 18 | 19 | - uses: actions/setup-node@v2 20 | with: 21 | node-version: "14.x" 22 | 23 | - name: Install dependencies 24 | run: | 25 | npm install -g bower 26 | npm install 27 | bower install --production 28 | 29 | - name: Build source 30 | run: npm run-script build 31 | 32 | - name: Run tests 33 | run: | 34 | bower install 35 | npm run-script test --if-present 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.* 2 | !/.gitignore 3 | !/.github/ 4 | /bower_components/ 5 | /node_modules/ 6 | /output/ 7 | package-lock.json 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 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). 4 | 5 | ## [Unreleased] 6 | 7 | Breaking changes: 8 | 9 | New features: 10 | 11 | Bugfixes: 12 | 13 | Other improvements: 14 | 15 | ## [v6.1.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v6.1.0) - 2022-04-27 16 | 17 | New features: 18 | - Added `bivoid` (#28 by @m-bock) 19 | 20 | ## [v6.0.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v6.0.0) - 2022-04-27 21 | 22 | Breaking changes: 23 | - Update project and deps to PureScript v0.15.0 (#25 by @JordanMartinez) 24 | 25 | New features: 26 | 27 | Bugfixes: 28 | 29 | Other improvements: 30 | 31 | ## [v5.0.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v5.0.0) - 2021-02-26 32 | 33 | Breaking changes: 34 | - Added support for PureScript 0.14 and dropped support for all previous versions (#16) 35 | - `Clown`, `Flip`, `Joker`, and `Product` have been moved to the `Data.Functors` module in the `purescript-functors` package, so that the same types can also be used as profunctors; `Product` was renamed to `Product2` (#22) 36 | - `Wrap` was deleted; it is expected that any instances of `Bifunctor` will be accompanied by a corresponding instance of `Functor` (#22) 37 | 38 | New features: 39 | 40 | Bugfixes: 41 | 42 | Other improvements: 43 | - Migrated CI to GitHub Actions and updated installation instructions to use Spago (#18) 44 | - Added a CHANGELOG.md file and pull request template (#19, #20) 45 | - This package now depends on the `purescript-const`, `purescript-either`, and `purescript-tuples` packages, and contains instances previously in those packages (#22) 46 | 47 | ## [v4.0.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v4.0.0) - 2018-05-23 48 | 49 | Updated for PureScript 0.12 50 | 51 | ## [v3.0.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v3.0.0) - 2017-03-25 52 | 53 | - Updated for PureScript 0.11 54 | 55 | ## [v2.0.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v2.0.0) - 2016-10-02 56 | 57 | - Updated dependencies 58 | - The `Product` data constructor is now called `Product` rather than `Pair` 59 | - Added some previously absent `Eq`, `Ord`, and `Show` instances for the newtypes 60 | - Added `Newtype` instances for the newtypes 61 | 62 | ## [v1.0.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v1.0.0) - 2016-06-01 63 | 64 | This release is intended for the PureScript 0.9.1 compiler and newer. 65 | 66 | **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. 67 | 68 | ## [v1.0.0-rc.1](https://github.com/purescript/purescript-bifunctors/releases/tag/v1.0.0-rc.1) - 2016-03-13 69 | 70 | - Release candidate for the psc 0.8+ core libraries 71 | 72 | ## [v0.4.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.4.0) - 2015-06-30 73 | 74 | 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. 75 | 76 | ## [v0.4.0-rc.1](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.4.0-rc.1) - 2015-06-06 77 | 78 | Initial release candidate of the library intended for the 0.7 compiler. 79 | 80 | ## [v0.3.1](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.3.1) - 2015-03-18 81 | 82 | Update docs. 83 | 84 | ## [v0.3.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.3.0) - 2015-03-15 85 | 86 | Bump `const` dependency. 87 | 88 | ## [v0.2.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.2.0) - 2015-02-21 89 | 90 | **This release requires PureScript v0.6.8 or later** 91 | - Updated dependencies 92 | 93 | ## [v0.1.0](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.1.0) - 2015-01-10 94 | 95 | - Updated `purescript-foldable-traversable` and `purescript-const` dependencies (@garyb) 96 | 97 | ## [v0.0.6](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.0.6) - 2014-10-27 98 | 99 | - Fix `bower.json` (@garyb) 100 | 101 | ## [v0.0.5](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.0.5) - 2014-10-27 102 | 103 | - Added `Const` instance (@garyb) 104 | 105 | ## [v0.0.4](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.0.4) - 2014-08-14 106 | 107 | - Updated dependencies (@garyb) 108 | 109 | ## [v0.0.3](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.0.3) - 2014-07-19 110 | 111 | - Fixed module name for `Clown` (@DylanLukes) 112 | 113 | ## [v0.0.2](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.0.2) - 2014-07-15 114 | 115 | - Added `Clown`, `Joker`, `Flip`, `Wrap`, `Join` and `Product` (@DylanLukes) 116 | 117 | ## [v0.0.1](https://github.com/purescript/purescript-bifunctors/releases/tag/v0.0.1) - 2014-05-21 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 PureScript 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation and/or 11 | other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors 14 | may be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # purescript-bifunctors 2 | 3 | [![Latest release](http://img.shields.io/github/release/purescript/purescript-bifunctors.svg)](https://github.com/purescript/purescript-bifunctors/releases) 4 | [![Build status](https://github.com/purescript/purescript-bifunctors/workflows/CI/badge.svg?branch=master)](https://github.com/purescript/purescript-bifunctors/actions?query=workflow%3ACI+branch%3Amaster) 5 | [![Pursuit](https://pursuit.purescript.org/packages/purescript-bifunctors/badge)](https://pursuit.purescript.org/packages/purescript-bifunctors) 6 | 7 | Bifunctors and biapplicatives. 8 | 9 | ## Installation 10 | 11 | ``` 12 | spago install bifunctors 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-bifunctors). 18 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-bifunctors", 3 | "homepage": "https://github.com/purescript/purescript-bifunctors", 4 | "description": "Bifunctors and biapplicatives", 5 | "license": "BSD-3-Clause", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/purescript/purescript-bifunctors.git" 9 | }, 10 | "ignore": [ 11 | "**/.*", 12 | "bower_components", 13 | "node_modules", 14 | "output", 15 | "test", 16 | "bower.json", 17 | "package.json" 18 | ], 19 | "dependencies": { 20 | "purescript-const": "^6.0.0", 21 | "purescript-either": "^6.0.0", 22 | "purescript-newtype": "^5.0.0", 23 | "purescript-prelude": "^6.0.0", 24 | "purescript-tuples": "^7.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "clean": "rimraf output && rimraf .pulp-cache", 5 | "build": "pulp build -- --censor-lib --strict" 6 | }, 7 | "devDependencies": { 8 | "pulp": "16.0.0-0", 9 | "purescript-psa": "^0.8.2", 10 | "rimraf": "^3.0.2" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Control/Biapplicative.purs: -------------------------------------------------------------------------------- 1 | module Control.Biapplicative where 2 | 3 | import Control.Biapply (class Biapply) 4 | import Data.Tuple (Tuple(..)) 5 | 6 | -- | `Biapplicative` captures type constructors of two arguments which support lifting of 7 | -- | functions of zero or more arguments, in the sense of `Applicative`. 8 | class Biapply w <= Biapplicative w where 9 | bipure :: forall a b. a -> b -> w a b 10 | 11 | instance biapplicativeTuple :: Biapplicative Tuple where 12 | bipure = Tuple 13 | -------------------------------------------------------------------------------- /src/Control/Biapply.purs: -------------------------------------------------------------------------------- 1 | module Control.Biapply where 2 | 3 | import Data.Function (const, identity) 4 | 5 | import Data.Bifunctor (class Bifunctor, bimap) 6 | import Data.Tuple (Tuple(..)) 7 | 8 | -- | A convenience operator which can be used to apply the result of `bipure` in 9 | -- | the style of `Applicative`: 10 | -- | 11 | -- | ```purescript 12 | -- | bipure f g <<$>> x <<*>> y 13 | -- | ``` 14 | infixl 4 identity as <<$>> 15 | 16 | -- | `Biapply` captures type constructors of two arguments which support lifting of 17 | -- | functions of one or more arguments, in the sense of `Apply`. 18 | class Bifunctor w <= Biapply w where 19 | biapply :: forall a b c d. w (a -> b) (c -> d) -> w a c -> w b d 20 | 21 | infixl 4 biapply as <<*>> 22 | 23 | -- | Keep the results of the second computation. 24 | biapplyFirst :: forall w a b c d. Biapply w => w a b -> w c d -> w c d 25 | biapplyFirst a b = bimap (const identity) (const identity) <<$>> a <<*>> b 26 | 27 | infixl 4 biapplyFirst as *>> 28 | 29 | -- | Keep the results of the first computation. 30 | biapplySecond :: forall w a b c d. Biapply w => w a b -> w c d -> w a b 31 | biapplySecond a b = bimap const const <<$>> a <<*>> b 32 | 33 | infixl 4 biapplySecond as <<* 34 | 35 | -- | Lift a function of two arguments. 36 | bilift2 37 | :: forall w a b c d e f 38 | . Biapply w 39 | => (a -> b -> c) 40 | -> (d -> e -> f) 41 | -> w a d 42 | -> w b e 43 | -> w c f 44 | bilift2 f g a b = bimap f g <<$>> a <<*>> b 45 | 46 | -- | Lift a function of three arguments. 47 | bilift3 48 | :: forall w a b c d e f g h 49 | . Biapply w 50 | => (a -> b -> c -> d) 51 | -> (e -> f -> g -> h) 52 | -> w a e 53 | -> w b f 54 | -> w c g 55 | -> w d h 56 | bilift3 f g a b c = bimap f g <<$>> a <<*>> b <<*>> c 57 | 58 | instance biapplyTuple :: Biapply Tuple where 59 | biapply (Tuple f g) (Tuple a b) = Tuple (f a) (g b) 60 | -------------------------------------------------------------------------------- /src/Data/Bifunctor.purs: -------------------------------------------------------------------------------- 1 | module Data.Bifunctor where 2 | 3 | import Control.Category (identity) 4 | import Data.Const (Const(..)) 5 | import Data.Either (Either(..)) 6 | import Data.Tuple (Tuple(..)) 7 | import Data.Unit (Unit, unit) 8 | import Data.Function (const) 9 | 10 | -- | A `Bifunctor` is a `Functor` from the pair category `(Type, Type)` to `Type`. 11 | -- | 12 | -- | A type constructor with two type arguments can be made into a `Bifunctor` if 13 | -- | both of its type arguments are covariant. 14 | -- | 15 | -- | The `bimap` function maps a pair of functions over the two type arguments 16 | -- | of the bifunctor. 17 | -- | 18 | -- | Laws: 19 | -- | 20 | -- | - Identity: `bimap identity identity == identity` 21 | -- | - Composition: `bimap f1 g1 <<< bimap f2 g2 == bimap (f1 <<< f2) (g1 <<< g2)` 22 | -- | 23 | class Bifunctor f where 24 | bimap :: forall a b c d. (a -> b) -> (c -> d) -> f a c -> f b d 25 | 26 | -- | Map a function over the first type argument of a `Bifunctor`. 27 | lmap :: forall f a b c. Bifunctor f => (a -> b) -> f a c -> f b c 28 | lmap f = bimap f identity 29 | 30 | -- | Map a function over the second type arguments of a `Bifunctor`. 31 | rmap :: forall f a b c. Bifunctor f => (b -> c) -> f a b -> f a c 32 | rmap = bimap identity 33 | 34 | -- | The bivoid function is used to ignore the types wrapped by a Bifunctor. 35 | bivoid :: forall f a b. Bifunctor f => f a b -> f Unit Unit 36 | bivoid = bimap (const unit) (const unit) 37 | 38 | instance bifunctorEither :: Bifunctor Either where 39 | bimap f _ (Left l) = Left (f l) 40 | bimap _ g (Right r) = Right (g r) 41 | 42 | instance bifunctorTuple :: Bifunctor Tuple where 43 | bimap f g (Tuple x y) = Tuple (f x) (g y) 44 | 45 | instance bifunctorConst :: Bifunctor Const where 46 | bimap f _ (Const a) = Const (f a) 47 | -------------------------------------------------------------------------------- /src/Data/Bifunctor/Join.purs: -------------------------------------------------------------------------------- 1 | module Data.Bifunctor.Join where 2 | 3 | import Prelude 4 | 5 | import Control.Biapplicative (class Biapplicative, bipure) 6 | import Control.Biapply (class Biapply, (<<*>>)) 7 | 8 | import Data.Bifunctor (class Bifunctor, bimap) 9 | import Data.Newtype (class Newtype) 10 | 11 | -- | Turns a `Bifunctor` into a `Functor` by equating the two type arguments. 12 | newtype Join :: forall k. (k -> k -> Type) -> k -> Type 13 | newtype Join p a = Join (p a a) 14 | 15 | derive instance newtypeJoin :: Newtype (Join p a) _ 16 | 17 | derive newtype instance eqJoin :: Eq (p a a) => Eq (Join p a) 18 | 19 | derive newtype instance ordJoin :: Ord (p a a) => Ord (Join p a) 20 | 21 | instance showJoin :: Show (p a a) => Show (Join p a) where 22 | show (Join x) = "(Join " <> show x <> ")" 23 | 24 | instance bifunctorJoin :: Bifunctor p => Functor (Join p) where 25 | map f (Join a) = Join (bimap f f a) 26 | 27 | instance biapplyJoin :: Biapply p => Apply (Join p) where 28 | apply (Join f) (Join a) = Join (f <<*>> a) 29 | 30 | instance biapplicativeJoin :: Biapplicative p => Applicative (Join p) where 31 | pure a = Join (bipure a a) 32 | --------------------------------------------------------------------------------