├── .gitignore ├── package.json ├── bower.json ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── ci.yml ├── .eslintrc.json ├── README.md ├── LICENSE ├── CHANGELOG.md └── src └── Data └── Function ├── Uncurried.js └── Uncurried.purs /.gitignore: -------------------------------------------------------------------------------- 1 | /.* 2 | !/.gitignore 3 | !/.eslintrc.json 4 | !/.github/ 5 | /bower_components/ 6 | /node_modules/ 7 | /output/ 8 | package-lock.json 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "clean": "rimraf output && rimraf .pulp-cache", 5 | "build": "eslint src && pulp build -- --censor-lib --strict" 6 | }, 7 | "devDependencies": { 8 | "eslint": "^7.15.0", 9 | "pulp": "16.0.0-0", 10 | "purescript-psa": "^0.8.2", 11 | "rimraf": "^3.0.2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-functions", 3 | "homepage": "https://github.com/purescript/purescript-functions", 4 | "license": "BSD-3-Clause", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/purescript/purescript-functions.git" 8 | }, 9 | "ignore": [ 10 | "**/.*", 11 | "bower_components", 12 | "node_modules", 13 | "output", 14 | "test", 15 | "bower.json", 16 | "package.json" 17 | ], 18 | "dependencies": { 19 | "purescript-prelude": "^6.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 6, 4 | "sourceType": "module" 5 | }, 6 | "extends": "eslint:recommended", 7 | "rules": { 8 | "strict": [2, "global"], 9 | "block-scoped-var": 2, 10 | "consistent-return": 2, 11 | "eqeqeq": [2, "smart"], 12 | "guard-for-in": 2, 13 | "no-caller": 2, 14 | "no-extend-native": 2, 15 | "no-loop-func": 2, 16 | "no-new": 2, 17 | "no-param-reassign": 2, 18 | "no-return-assign": 2, 19 | "no-unused-expressions": 2, 20 | "no-use-before-define": 2, 21 | "radix": [2, "always"], 22 | "indent": [2, 2], 23 | "quotes": [2, "double"], 24 | "semi": [2, "always"] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # purescript-functions 2 | 3 | [![Latest release](http://img.shields.io/github/release/purescript/purescript-functions.svg)](https://github.com/purescript/purescript-functions/releases) 4 | [![Build status](https://github.com/purescript/purescript-functions/workflows/CI/badge.svg?branch=master)](https://github.com/purescript/purescript-functions/actions?query=workflow%3ACI+branch%3Amaster) 5 | [![Pursuit](https://pursuit.purescript.org/packages/purescript-functions/badge)](https://pursuit.purescript.org/packages/purescript-functions) 6 | 7 | Function combinators and types for uncurried multi-argument functions. 8 | 9 | ## Installation 10 | 11 | ``` 12 | spago install functions 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-functions). 18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.0.0](https://github.com/purescript/purescript-functions/releases/tag/v6.0.0) - 2022-04-27 16 | 17 | Breaking changes: 18 | - Migrated FFI to ES modules (#19 by @kl0tl and @JordanMartinez) 19 | 20 | New features: 21 | 22 | Bugfixes: 23 | 24 | Other improvements: 25 | 26 | ## [v5.0.0](https://github.com/purescript/purescript-functions/releases/tag/v5.0.0) - 2021-02-26 27 | 28 | Breaking changes: 29 | - Added support for PureScript 0.14 and dropped support for all previous versions (#12) 30 | 31 | New features: 32 | - Added roles declarations to allow safe coercions (#12) 33 | 34 | Bugfixes: 35 | 36 | Other improvements: 37 | - Migrated CI to GitHub Actions and updated installation instructions to use Spago (#13) 38 | - Added a CHANGELOG.md file and pull request template (#14, #15) 39 | - Removed `return {}` from FFI functions for a small performance boost (#10) 40 | 41 | ## [v4.0.0](https://github.com/purescript/purescript-functions/releases/tag/v4.0.0) - 2018-05-22 42 | 43 | Updated for PureScript 0.12 44 | 45 | ## [v3.0.0](https://github.com/purescript/purescript-functions/releases/tag/v3.0.0) - 2017-03-26 46 | 47 | - Updated for PureScript 0.11 48 | 49 | ## [v2.0.0](https://github.com/purescript/purescript-functions/releases/tag/v2.0.0) - 2016-10-01 50 | 51 | - Updated dependencies 52 | - `Fn1` is now a synonym for `(->)` rather than introducing an unnecessary foreign type 53 | 54 | ## [v1.0.0](https://github.com/purescript/purescript-functions/releases/tag/v1.0.0) - 2016-06-01 55 | 56 | This release is intended for the PureScript 0.9.1 compiler and newer. 57 | 58 | **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. 59 | 60 | ## [v1.0.0-rc.1](https://github.com/purescript/purescript-functions/releases/tag/v1.0.0-rc.1) - 2016-03-13 61 | 62 | - Release candidate for the psc 0.8+ core libraries 63 | 64 | ## [v0.1.0](https://github.com/purescript/purescript-functions/releases/tag/v0.1.0) - 2015-06-30 65 | 66 | 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. 67 | 68 | ## [v0.1.0-rc.1](https://github.com/purescript/purescript-functions/releases/tag/v0.1.0-rc.1) - 2015-06-06 69 | 70 | Initial release candidate. 71 | 72 | -------------------------------------------------------------------------------- /src/Data/Function/Uncurried.js: -------------------------------------------------------------------------------- 1 | // module Data.Function.Uncurried 2 | 3 | export const mkFn0 = function (fn) { 4 | return function () { 5 | return fn(); 6 | }; 7 | }; 8 | 9 | export const mkFn2 = function (fn) { 10 | /* jshint maxparams: 2 */ 11 | return function (a, b) { 12 | return fn(a)(b); 13 | }; 14 | }; 15 | 16 | export const mkFn3 = function (fn) { 17 | /* jshint maxparams: 3 */ 18 | return function (a, b, c) { 19 | return fn(a)(b)(c); 20 | }; 21 | }; 22 | 23 | export const mkFn4 = function (fn) { 24 | /* jshint maxparams: 4 */ 25 | return function (a, b, c, d) { 26 | return fn(a)(b)(c)(d); 27 | }; 28 | }; 29 | 30 | export const mkFn5 = function (fn) { 31 | /* jshint maxparams: 5 */ 32 | return function (a, b, c, d, e) { 33 | return fn(a)(b)(c)(d)(e); 34 | }; 35 | }; 36 | 37 | export const mkFn6 = function (fn) { 38 | /* jshint maxparams: 6 */ 39 | return function (a, b, c, d, e, f) { 40 | return fn(a)(b)(c)(d)(e)(f); 41 | }; 42 | }; 43 | 44 | export const mkFn7 = function (fn) { 45 | /* jshint maxparams: 7 */ 46 | return function (a, b, c, d, e, f, g) { 47 | return fn(a)(b)(c)(d)(e)(f)(g); 48 | }; 49 | }; 50 | 51 | export const mkFn8 = function (fn) { 52 | /* jshint maxparams: 8 */ 53 | return function (a, b, c, d, e, f, g, h) { 54 | return fn(a)(b)(c)(d)(e)(f)(g)(h); 55 | }; 56 | }; 57 | 58 | export const mkFn9 = function (fn) { 59 | /* jshint maxparams: 9 */ 60 | return function (a, b, c, d, e, f, g, h, i) { 61 | return fn(a)(b)(c)(d)(e)(f)(g)(h)(i); 62 | }; 63 | }; 64 | 65 | export const mkFn10 = function (fn) { 66 | /* jshint maxparams: 10 */ 67 | return function (a, b, c, d, e, f, g, h, i, j) { 68 | return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)(j); 69 | }; 70 | }; 71 | 72 | export const runFn0 = function (fn) { 73 | return fn(); 74 | }; 75 | 76 | export const runFn2 = function (fn) { 77 | return function (a) { 78 | return function (b) { 79 | return fn(a, b); 80 | }; 81 | }; 82 | }; 83 | 84 | export const runFn3 = function (fn) { 85 | return function (a) { 86 | return function (b) { 87 | return function (c) { 88 | return fn(a, b, c); 89 | }; 90 | }; 91 | }; 92 | }; 93 | 94 | export const runFn4 = function (fn) { 95 | return function (a) { 96 | return function (b) { 97 | return function (c) { 98 | return function (d) { 99 | return fn(a, b, c, d); 100 | }; 101 | }; 102 | }; 103 | }; 104 | }; 105 | 106 | export const runFn5 = function (fn) { 107 | return function (a) { 108 | return function (b) { 109 | return function (c) { 110 | return function (d) { 111 | return function (e) { 112 | return fn(a, b, c, d, e); 113 | }; 114 | }; 115 | }; 116 | }; 117 | }; 118 | }; 119 | 120 | export const runFn6 = function (fn) { 121 | return function (a) { 122 | return function (b) { 123 | return function (c) { 124 | return function (d) { 125 | return function (e) { 126 | return function (f) { 127 | return fn(a, b, c, d, e, f); 128 | }; 129 | }; 130 | }; 131 | }; 132 | }; 133 | }; 134 | }; 135 | 136 | export const runFn7 = function (fn) { 137 | return function (a) { 138 | return function (b) { 139 | return function (c) { 140 | return function (d) { 141 | return function (e) { 142 | return function (f) { 143 | return function (g) { 144 | return fn(a, b, c, d, e, f, g); 145 | }; 146 | }; 147 | }; 148 | }; 149 | }; 150 | }; 151 | }; 152 | }; 153 | 154 | export const runFn8 = function (fn) { 155 | return function (a) { 156 | return function (b) { 157 | return function (c) { 158 | return function (d) { 159 | return function (e) { 160 | return function (f) { 161 | return function (g) { 162 | return function (h) { 163 | return fn(a, b, c, d, e, f, g, h); 164 | }; 165 | }; 166 | }; 167 | }; 168 | }; 169 | }; 170 | }; 171 | }; 172 | }; 173 | 174 | export const runFn9 = function (fn) { 175 | return function (a) { 176 | return function (b) { 177 | return function (c) { 178 | return function (d) { 179 | return function (e) { 180 | return function (f) { 181 | return function (g) { 182 | return function (h) { 183 | return function (i) { 184 | return fn(a, b, c, d, e, f, g, h, i); 185 | }; 186 | }; 187 | }; 188 | }; 189 | }; 190 | }; 191 | }; 192 | }; 193 | }; 194 | }; 195 | 196 | export const runFn10 = function (fn) { 197 | return function (a) { 198 | return function (b) { 199 | return function (c) { 200 | return function (d) { 201 | return function (e) { 202 | return function (f) { 203 | return function (g) { 204 | return function (h) { 205 | return function (i) { 206 | return function (j) { 207 | return fn(a, b, c, d, e, f, g, h, i, j); 208 | }; 209 | }; 210 | }; 211 | }; 212 | }; 213 | }; 214 | }; 215 | }; 216 | }; 217 | }; 218 | }; 219 | -------------------------------------------------------------------------------- /src/Data/Function/Uncurried.purs: -------------------------------------------------------------------------------- 1 | module Data.Function.Uncurried where 2 | 3 | import Data.Unit (Unit) 4 | 5 | -- | A function of zero arguments 6 | foreign import data Fn0 :: Type -> Type 7 | 8 | type role Fn0 representational 9 | 10 | -- | A function of one argument 11 | type Fn1 a b = a -> b 12 | 13 | -- | A function of two arguments 14 | foreign import data Fn2 :: Type -> Type -> Type -> Type 15 | 16 | type role Fn2 representational representational representational 17 | 18 | -- | A function of three arguments 19 | foreign import data Fn3 :: Type -> Type -> Type -> Type -> Type 20 | 21 | type role Fn3 representational representational representational representational 22 | 23 | -- | A function of four arguments 24 | foreign import data Fn4 :: Type -> Type -> Type -> Type -> Type -> Type 25 | 26 | type role Fn4 representational representational representational representational representational 27 | 28 | -- | A function of five arguments 29 | foreign import data Fn5 :: Type -> Type -> Type -> Type -> Type -> Type -> Type 30 | 31 | type role Fn5 representational representational representational representational representational representational 32 | 33 | -- | A function of six arguments 34 | foreign import data Fn6 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type 35 | 36 | type role Fn6 representational representational representational representational representational representational representational 37 | 38 | -- | A function of seven arguments 39 | foreign import data Fn7 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type 40 | 41 | type role Fn7 representational representational representational representational representational representational representational representational 42 | 43 | -- | A function of eight arguments 44 | foreign import data Fn8 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type 45 | 46 | type role Fn8 representational representational representational representational representational representational representational representational representational 47 | 48 | -- | A function of nine arguments 49 | foreign import data Fn9 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type 50 | 51 | type role Fn9 representational representational representational representational representational representational representational representational representational representational 52 | 53 | -- | A function of ten arguments 54 | foreign import data Fn10 :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type 55 | 56 | type role Fn10 representational representational representational representational representational representational representational representational representational representational representational 57 | 58 | -- | Create a function of no arguments 59 | foreign import mkFn0 :: forall a. (Unit -> a) -> Fn0 a 60 | 61 | -- | Create a function of one argument 62 | mkFn1 :: forall a b. (a -> b) -> Fn1 a b 63 | mkFn1 f = f 64 | 65 | -- | Create a function of two arguments from a curried function 66 | foreign import mkFn2 :: forall a b c. (a -> b -> c) -> Fn2 a b c 67 | 68 | -- | Create a function of three arguments from a curried function 69 | foreign import mkFn3 :: forall a b c d. (a -> b -> c -> d) -> Fn3 a b c d 70 | 71 | -- | Create a function of four arguments from a curried function 72 | foreign import mkFn4 :: forall a b c d e. (a -> b -> c -> d -> e) -> Fn4 a b c d e 73 | 74 | -- | Create a function of five arguments from a curried function 75 | foreign import mkFn5 :: forall a b c d e f. (a -> b -> c -> d -> e -> f) -> Fn5 a b c d e f 76 | 77 | -- | Create a function of six arguments from a curried function 78 | foreign import mkFn6 :: forall a b c d e f g. (a -> b -> c -> d -> e -> f -> g) -> Fn6 a b c d e f g 79 | 80 | -- | Create a function of seven arguments from a curried function 81 | foreign import mkFn7 :: forall a b c d e f g h. (a -> b -> c -> d -> e -> f -> g -> h) -> Fn7 a b c d e f g h 82 | 83 | -- | Create a function of eight arguments from a curried function 84 | foreign import mkFn8 :: forall a b c d e f g h i. (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Fn8 a b c d e f g h i 85 | 86 | -- | Create a function of nine arguments from a curried function 87 | foreign import mkFn9 :: forall a b c d e f g h i j. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> Fn9 a b c d e f g h i j 88 | 89 | -- | Create a function of ten arguments from a curried function 90 | foreign import mkFn10 :: forall a b c d e f g h i j k. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> Fn10 a b c d e f g h i j k 91 | 92 | -- | Apply a function of no arguments 93 | foreign import runFn0 :: forall a. Fn0 a -> a 94 | 95 | -- | Apply a function of one argument 96 | runFn1 :: forall a b. Fn1 a b -> a -> b 97 | runFn1 f = f 98 | 99 | -- | Apply a function of two arguments 100 | foreign import runFn2 :: forall a b c. Fn2 a b c -> a -> b -> c 101 | 102 | -- | Apply a function of three arguments 103 | foreign import runFn3 :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d 104 | 105 | -- | Apply a function of four arguments 106 | foreign import runFn4 :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e 107 | 108 | -- | Apply a function of five arguments 109 | foreign import runFn5 :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f 110 | 111 | -- | Apply a function of six arguments 112 | foreign import runFn6 :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g 113 | 114 | -- | Apply a function of seven arguments 115 | foreign import runFn7 :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h 116 | 117 | -- | Apply a function of eight arguments 118 | foreign import runFn8 :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i 119 | 120 | -- | Apply a function of nine arguments 121 | foreign import runFn9 :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j 122 | 123 | -- | Apply a function of ten arguments 124 | foreign import runFn10 :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k 125 | --------------------------------------------------------------------------------