diff --git a/LICENSE b/LICENSE
index 48a84dd0..ffd105b7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2017 Sanctuary
+Copyright (c) 2018 Sanctuary
Copyright (c) 2016 Plaid Technologies, Inc.
Permission is hereby granted, free of charge, to any person
diff --git a/README.md b/README.md
index 91fc96f0..23608244 100644
--- a/README.md
+++ b/README.md
@@ -29,10 +29,148 @@ If `words` is `[]` we'll get a familiar error at run-time:
Sanctuary gives us a fighting chance of avoiding such errors. We might
write:
- S.map(S.toUpper, S.head(words))
+ S.map (S.toUpper) (S.head (words))
Sanctuary is designed to work in Node.js and in ES5-compatible browsers.
+## Ramda
+
+[Ramda][] provides several functions which return problematic values
+such as `undefined`, `Infinity`, or `NaN` when applied to unsuitable
+inputs. These are known as [partial functions][]. Partial functions
+necessitate the use of guards or null checks. In order to safely use
+`R.head`, for example, one must ensure that the array is non-empty:
+
+ if (R.isEmpty (xs)) {
+ // ...
+ } else {
+ return f (R.head (xs));
+ }
+
+Using the Maybe type renders such guards (and null checks) unnecessary.
+Changing functions such as `R.head` to return Maybe values was proposed
+in [ramda/ramda#683][], but was considered too much of a stretch for
+JavaScript programmers. Sanctuary was released the following month,
+in January 2015, as a companion library to Ramda.
+
+In addition to broadening in scope in the years since its release,
+Sanctuary's philosophy has diverged from Ramda's in several respects.
+
+### Totality
+
+Every Sanctuary function is defined for every value which is a member of
+the function's input type. Such functions are known as [total functions][].
+Ramda, on the other hand, contains a number of [partial functions][].
+
+### Information preservation
+
+Certain Sanctuary functions preserve more information than their Ramda
+counterparts. Examples:
+
+ |> R.tail ([]) |> S.tail ([])
+ [] Nothing
+
+ |> R.tail (['foo']) |> S.tail (['foo'])
+ [] Just ([])
+
+ |> R.replace (/^x/) ('') ('abc') |> S.stripPrefix ('x') ('abc')
+ 'abc' Nothing
+
+ |> R.replace (/^x/) ('') ('xabc') |> S.stripPrefix ('x') ('xabc')
+ 'abc' Just ('abc')
+
+### Invariants
+
+Sanctuary performs rigorous [type checking][] of inputs and outputs, and
+throws a descriptive error if a type error is encountered. This allows bugs
+to be caught and fixed early in the development cycle.
+
+Ramda operates on the [garbage in, garbage out][GIGO] principal. Functions
+are documented to take arguments of particular types, but these invariants
+are not enforced. The problem with this approach in a language as
+permissive as JavaScript is that there's no guarantee that garbage input
+will produce garbage output ([ramda/ramda#1413][]). Ramda performs ad hoc
+type checking in some such cases ([ramda/ramda#1419][]).
+
+Sanctuary can be configured to operate in garbage in, garbage out mode.
+Ramda cannot be configured to enforce its invariants.
+
+### Currying
+
+Sanctuary functions are curried. There is, for example, exactly one way to
+apply `S.reduce` to `S.add`, `0`, and `xs`:
+
+ - `S.reduce (S.add) (0) (xs)`
+
+Ramda functions are also curried, but in a complex manner. There are four
+ways to apply `R.reduce` to `R.add`, `0`, and `xs`:
+
+ - `R.reduce (R.add) (0) (xs)`
+ - `R.reduce (R.add) (0, xs)`
+ - `R.reduce (R.add, 0) (xs)`
+ - `R.reduce (R.add, 0, xs)`
+
+Ramda supports all these forms because curried functions enable partial
+application, one of the library's tenets, but `f(x)(y)(z)` is considered
+too unfamiliar and too unattractive to appeal to JavaScript programmers.
+
+Sanctuary's developers prefer a simple, unfamiliar construct to a complex,
+familiar one. Familiarity can be acquired; complexity is intrinsic.
+
+The lack of breathing room in `f(x)(y)(z)` impairs readability. The simple
+solution to this problem, proposed in [#438][], is to include a space when
+applying a function: `f (x) (y) (z)`.
+
+Ramda also provides a special placeholder value, [`R.__`][], which removes
+the restriction that a function must be applied to its arguments in order.
+The following expressions are equivalent:
+
+ - `R.reduce (R.__, 0, xs) (R.add)`
+ - `R.reduce (R.add, R.__, xs) (0)`
+ - `R.reduce (R.__, 0) (R.add) (xs)`
+ - `R.reduce (R.__, 0) (R.add, xs)`
+ - `R.reduce (R.__, R.__, xs) (R.add) (0)`
+ - `R.reduce (R.__, R.__, xs) (R.add, 0)`
+
+### Variadic functions
+
+Ramda provides several functions which take any number of arguments. These
+are known as [variadic functions][]. Additionally, Ramda provides several
+functions which take variadic functions as arguments. Although natural in
+a dynamically typed language, variadic functions are at odds with the type
+notation Ramda and Sanctuary both use, leading to some indecipherable type
+signatures such as this one:
+
+ R.lift :: (*... -> *...) -> ([*]... -> [*])
+
+Sanctuary has no variadic functions, nor any functions which take variadic
+functions as arguments. Sanctuary provides two "lift" functions, each with
+a helpful type signature:
+
+ S.lift2 :: Apply f => (a -> b -> c) -> f a -> f b -> f c
+ S.lift3 :: Apply f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
+
+### Implicit context
+
+Ramda provides [`R.bind`][] and [`R.invoker`][] for working with methods.
+Additionally, many Ramda functions use `Function#call` or `Function#apply`
+to preserve context. Sanctuary makes no allowances for `this`.
+
+### Transducers
+
+Several Ramda functions act as transducers. Sanctuary provides no support
+for transducers.
+
+### Modularity
+
+Whereas Ramda has no dependencies, Sanctuary has a modular design:
+[sanctuary-def][] provides type checking, [sanctuary-type-classes][]
+provides Fantasy Land functions and type classes, [sanctuary-show][]
+provides string representations, and algebraic data types are provided
+by [sanctuary-either][], [sanctuary-maybe][], and [sanctuary-pair][].
+Not only does this approach reduce the complexity of Sanctuary itself,
+but it allows these components to be reused in other contexts.
+
## Types
Sanctuary uses Haskell-like type signatures to describe the types of
@@ -119,20 +257,6 @@ Functor type class. Type-class constraints appear at the beginning of a
type signature, separated from the rest of the signature by a fat arrow
(`=>`).
-### Type representatives
-
-What is the type of `Number`? One answer is `a -> Number`, since it's a
-function which takes an argument of any type and returns a Number value.
-When provided as the first argument to [`is`](#is), though, `Number` is
-really the value-level representative of the Number type.
-
-Sanctuary uses the TypeRep pseudotype to describe type representatives.
-For example:
-
- Number :: TypeRep Number
-
-`Number` is the sole inhabitant of the TypeRep Number type.
-
## Type checking
Sanctuary functions are defined via [sanctuary-def][] to provide run-time
@@ -141,7 +265,7 @@ are reported immediately, avoiding circuitous stack traces (at best) and
silent failures due to type coercion (at worst). For example:
```javascript
-S.add(2, true);
+S.add (2) (true);
// ! TypeError: Invalid value
//
// add :: FiniteNumber -> FiniteNumber -> FiniteNumber
@@ -152,34 +276,66 @@ S.add(2, true);
//
// The value at position 1 is not a member of ‘FiniteNumber’.
//
-// See https://github.com/sanctuary-js/sanctuary-def/tree/v0.14.0#FiniteNumber for information about the sanctuary-def/FiniteNumber type.
+// See https://github.com/sanctuary-js/sanctuary-def/tree/v0.18.1#FiniteNumber for information about the sanctuary-def/FiniteNumber type.
```
Compare this to the behaviour of Ramda's unchecked equivalent:
```javascript
-R.add(2, true);
+R.add (2) (true);
// => 3
```
-There is a performance cost to run-time type checking. One may wish to
-disable type checking in certain contexts to avoid paying this cost.
-[`create`](#create) facilitates the creation of a Sanctuary module which
-does not perform type checking.
-
-In Node, one could use an environment variable to determine whether to
-perform type checking:
+There is a performance cost to run-time type checking. Type checking is
+disabled by default if `process.env.NODE_ENV` is `'production'`. If this
+rule is unsuitable for a given program, one may use [`create`](#create)
+to create a Sanctuary module based on a different rule. For example:
```javascript
-const {create, env} = require('sanctuary');
+const S = sanctuary.create ({
+ checkTypes: localStorage.getItem ('SANCTUARY_CHECK_TYPES') === 'true',
+ env: sanctuary.env,
+});
+```
+
+Occasionally one may wish to perform an operation which is not type safe,
+such as mapping over an object with heterogeneous values. This is possible
+via selective use of [`unchecked`](#unchecked) functions.
-const checkTypes = process.env.NODE_ENV !== 'production';
-const S = create({checkTypes, env});
+## Installation
+
+`npm install sanctuary` will install Sanctuary for use in Node.js.
+
+Running Sanctuary in the browser is more involved. One must include a
+`
+
+
+
+
+
+
+
+```
+
+To ensure compatibility one should use the dependency versions specified
+in __package.json__.
+
+For convenience one could define aliases for various modules:
+
+```javascript
+const S = window.sanctuary;
+const $ = window.sanctuaryDef;
+// ...
```
## API
-
+### Configure
+
+#### `create :: { checkTypes :: Boolean, env :: Array Type } -> Module`
Takes an options record and returns a Sanctuary module. `checkTypes`
specifies whether to enable type checking. The module's polymorphic
@@ -195,136 +351,155 @@ The following snippet demonstrates defining a custom type and using
`create` to produce a Sanctuary module which is aware of that type:
```javascript
-const {create, env} = require('sanctuary');
-const $ = require('sanctuary-def');
-const type = require('sanctuary-type-identifiers');
+const {create, env} = require ('sanctuary');
+const $ = require ('sanctuary-def');
+const type = require ('sanctuary-type-identifiers');
// Identity :: a -> Identity a
-const Identity = function Identity(x) {
- if (!(this instanceof Identity)) return new Identity(x);
- this.value = x;
+const Identity = x => {
+ const identity = Object.create (Identity$prototype);
+ identity.value = x;
+ return identity;
};
Identity['@@type'] = 'my-package/Identity@1';
-Identity.prototype['fantasy-land/map'] = function(f) {
- return Identity(f(this.value));
+const Identity$prototype = {
+ 'constructor': Identity,
+ '@@show': function() { return `Identity (${S.show (this.value)})`; },
+ 'fantasy-land/map': function(f) { return Identity (f (this.value)); },
};
// IdentityType :: Type -> Type
-const IdentityType = $.UnaryType(
- Identity['@@type'],
- 'http://example.com/my-package#Identity',
- x => type(x) === Identity['@@type'],
- identity => [identity.value]
-);
-
-const S = create({
+const IdentityType = $.UnaryType
+ (Identity['@@type'])
+ ('http://example.com/my-package#Identity')
+ (x => type (x) === Identity['@@type'])
+ (identity => [identity.value]);
+
+const S = create ({
checkTypes: process.env.NODE_ENV !== 'production',
- env: env.concat([IdentityType($.Unknown)]),
+ env: env.concat ([IdentityType ($.Unknown)]),
});
-S.map(S.sub(1), Identity(43));
-// => Identity(42)
+S.map (S.sub (1)) (Identity (43));
+// => Identity (42)
```
See also [`env`](#env).
-
-
-The default environment, which may be used as is or as the basis of a
-custom environment in conjunction with [`create`](#create).
+#### `env :: Array Type`
-### Placeholder
+The Sanctuary module's environment (`(S.create ({checkTypes, env})).env`
+is a reference to `env`). Useful in conjunction with [`create`](#create).
-Sanctuary functions are designed with partial application in mind.
-In many cases one can define a more specific function in terms of
-a more general one simply by applying the more general function to
-some (but not all) of its arguments. For example, one could define
-`sum :: Foldable f => f Number -> Number` as `S.reduce(S.add, 0)`.
+```javascript
+> S.env
+[ $.AnyFunction,
+. $.Arguments,
+. $.Array ($.Unknown),
+. $.Boolean,
+. $.Date,
+. $.Error,
+. $.HtmlElement,
+. $.Null,
+. $.Number,
+. $.Object,
+. $.RegExp,
+. $.StrMap ($.Unknown),
+. $.String,
+. $.Symbol,
+. $.Undefined,
+. $.FiniteNumber,
+. $.NonZeroFiniteNumber,
+. S.EitherType ($.Unknown) ($.Unknown),
+. $.Function ([$.Unknown, $.Unknown]),
+. $.GlobalRegExp,
+. $.NonGlobalRegExp,
+. $.Integer,
+. $.NonNegativeInteger,
+. S.MaybeType ($.Unknown),
+. $.Array2 ($.Unknown) ($.Unknown),
+. S.PairType ($.Unknown) ($.Unknown),
+. $.RegexFlags,
+. $.Type,
+. $.TypeClass,
+. $.ValidDate,
+. $.ValidNumber ]
+```
-In some cases, though, there are multiple orders in which one may
-wish to provide a function's arguments. `S.concat('prefix')` is a
-function which prefixes its argument, but how would one define a
-function which suffixes its argument? It's possible with the help
-of [`__`](#__), the special placeholder value.
+#### `unchecked :: Module`
-The placeholder indicates a hole to be filled at some future time.
-The following are all equivalent (`_` represents the placeholder):
+A complete Sanctuary module which performs no type checking. This is
+useful as it permits operations which Sanctuary's type checking would
+disallow, such as mapping over an object with heterogeneous values.
- - `f(x, y, z)`
- - `f(_, y, z)(x)`
- - `f(_, _, z)(x, y)`
- - `f(_, _, z)(_, y)(x)`
+See also [`create`](#create).
-
+```javascript
+> S.unchecked.map (S.show) ({x: 'foo', y: true, z: 42})
+{x: '"foo"', y: 'true', z: '42'}
+```
-The special [placeholder](#placeholder) value.
+Opting out of type checking may cause type errors to go unnoticed.
```javascript
-> S.map(S.concat('@'), ['foo', 'bar', 'baz'])
-['@foo', '@bar', '@baz']
-
-> S.map(S.concat(S.__, '?'), ['foo', 'bar', 'baz'])
-['foo?', 'bar?', 'baz?']
+> S.unchecked.add (2) ('2')
+'22'
```
### Classify
-
+#### `type :: Any -> { namespace :: Maybe String, name :: String, version :: NonNegativeInteger }`
Returns the result of parsing the [type identifier][] of the given value.
```javascript
-> S.type(S.Just(42))
-{namespace: Just('sanctuary'), name: 'Maybe', version: 0}
+> S.type (S.Just (42))
+{namespace: Just ('sanctuary-maybe'), name: 'Maybe', version: 1}
-> S.type([1, 2, 3])
+> S.type ([1, 2, 3])
{namespace: Nothing, name: 'Array', version: 0}
```
-
+#### `is :: Type -> Any -> Boolean`
-Takes a [type representative](#type-representatives) and a value of any
-type and returns `true` [iff][] the given value is of the specified type.
-Subtyping is not respected.
+Returns `true` [iff][] the given value is a member of the specified type.
+See [`$.test`][] for details.
```javascript
-> S.is(Number, 42)
+> S.is ($.Array ($.Integer)) ([1, 2, 3])
true
-> S.is(Object, 42)
-false
-
-> S.is(String, 42)
+> S.is ($.Array ($.Integer)) ([1, 2, 3.14])
false
```
### Showable
-
+#### `show :: Any -> String`
-Alias of [`Z.toString`][].
+Alias of [`show`][].
```javascript
-> S.toString(-0)
+> S.show (-0)
'-0'
-> S.toString(['foo', 'bar', 'baz'])
+> S.show (['foo', 'bar', 'baz'])
'["foo", "bar", "baz"]'
-> S.toString({x: 1, y: 2, z: 3})
+> S.show ({x: 1, y: 2, z: 3})
'{"x": 1, "y": 2, "z": 3}'
-> S.toString(S.Left(S.Right(S.Just(S.Nothing))))
-'Left(Right(Just(Nothing)))'
+> S.show (S.Left (S.Right (S.Just (S.Nothing))))
+'Left (Right (Just (Nothing)))'
```
### Fantasy Land
Sanctuary is compatible with the [Fantasy Land][] specification.
-
+#### `equals :: Setoid a => a -> a -> Boolean`
Curried version of [`Z.equals`][] which requires two arguments of the
same type.
@@ -334,248 +509,247 @@ create a Sanctuary module with type checking disabled, then use that
module's `equals` function.
```javascript
-> S.equals(0, -0)
+> S.equals (0) (-0)
true
-> S.equals(NaN, NaN)
+> S.equals (NaN) (NaN)
true
-> S.equals(S.Just([1, 2, 3]), S.Just([1, 2, 3]))
+> S.equals (S.Just ([1, 2, 3])) (S.Just ([1, 2, 3]))
true
-> S.equals(S.Just([1, 2, 3]), S.Just([1, 2, 4]))
+> S.equals (S.Just ([1, 2, 3])) (S.Just ([1, 2, 4]))
false
```
-
+#### `lt :: Ord a => a -> a -> Boolean`
Returns `true` [iff][] the *second* argument is less than the first
-according to [`Z.lt`][]. The arguments must be provided one at a time.
-
-See also [`lt_`](#lt_).
-
-```javascript
-> S.filter(S.lt(3), [1, 2, 3, 4, 5])
-[1, 2]
-```
-
-
-
-Returns `true` [iff][] the first argument is less than the second
according to [`Z.lt`][].
-See also [`lt`](#lt).
-
```javascript
-> S.lt_([1, 2, 3], [1, 2, 3])
-false
-
-> S.lt_([1, 2, 3], [1, 2, 4])
-true
-
-> S.lt_([1, 2, 3], [1, 2])
-false
+> S.filter (S.lt (3)) ([1, 2, 3, 4, 5])
+[1, 2]
```
-
+#### `lte :: Ord a => a -> a -> Boolean`
Returns `true` [iff][] the *second* argument is less than or equal to
-the first according to [`Z.lte`][]. The arguments must be provided one
-at a time.
-
-See also [`lte_`](#lte_).
+the first according to [`Z.lte`][].
```javascript
-> S.filter(S.lte(3), [1, 2, 3, 4, 5])
+> S.filter (S.lte (3)) ([1, 2, 3, 4, 5])
[1, 2, 3]
```
-
-
-Returns `true` [iff][] the first argument is less than or equal to the
-second according to [`Z.lte`][].
-
-See also [`lte`](#lte).
-
-```javascript
-> S.lte_([1, 2, 3], [1, 2, 3])
-true
-
-> S.lte_([1, 2, 3], [1, 2, 4])
-true
-
-> S.lte_([1, 2, 3], [1, 2])
-false
-```
-
-
+#### `gt :: Ord a => a -> a -> Boolean`
Returns `true` [iff][] the *second* argument is greater than the first
-according to [`Z.gt`][]. The arguments must be provided one at a time.
-
-See also [`gt_`](#gt_).
-
-```javascript
-> S.filter(S.gt(3), [1, 2, 3, 4, 5])
-[4, 5]
-```
-
-
-
-Returns `true` [iff][] the first argument is greater than the second
according to [`Z.gt`][].
-See also [`gt`](#gt).
-
```javascript
-> S.gt_([1, 2, 3], [1, 2, 3])
-false
-
-> S.gt_([1, 2, 3], [1, 2, 4])
-false
-
-> S.gt_([1, 2, 3], [1, 2])
-true
+> S.filter (S.gt (3)) ([1, 2, 3, 4, 5])
+[4, 5]
```
-
+#### `gte :: Ord a => a -> a -> Boolean`
Returns `true` [iff][] the *second* argument is greater than or equal
-to the first according to [`Z.gte`][]. The arguments must be provided
-one at a time.
-
-See also [`gte_`](#gte_).
+to the first according to [`Z.gte`][].
```javascript
-> S.filter(S.gte(3), [1, 2, 3, 4, 5])
+> S.filter (S.gte (3)) ([1, 2, 3, 4, 5])
[3, 4, 5]
```
-
-
-Returns `true` [iff][] the first argument is greater than or equal to
-the second according to [`Z.gte`][].
-
-See also [`gte`](#gte).
-
-```javascript
-> S.gte_([1, 2, 3], [1, 2, 3])
-true
-
-> S.gte_([1, 2, 3], [1, 2, 4])
-false
-
-> S.gte_([1, 2, 3], [1, 2])
-true
-```
-
-
+#### `min :: Ord a => a -> a -> a`
Returns the smaller of its two arguments (according to [`Z.lte`][]).
See also [`max`](#max).
```javascript
-> S.min(10, 2)
+> S.min (10) (2)
2
-> S.min(new Date('1999-12-31'), new Date('2000-01-01'))
-new Date('1999-12-31')
+> S.min (new Date ('1999-12-31')) (new Date ('2000-01-01'))
+new Date ('1999-12-31')
-> S.min('10', '2')
+> S.min ('10') ('2')
'10'
```
-
+#### `max :: Ord a => a -> a -> a`
Returns the larger of its two arguments (according to [`Z.lte`][]).
See also [`min`](#min).
```javascript
-> S.max(10, 2)
+> S.max (10) (2)
10
-> S.max(new Date('1999-12-31'), new Date('2000-01-01'))
-new Date('2000-01-01')
+> S.max (new Date ('1999-12-31')) (new Date ('2000-01-01'))
+new Date ('2000-01-01')
-> S.max('10', '2')
+> S.max ('10') ('2')
'2'
```
-
+#### `id :: Category c => TypeRep c -> c`
[Type-safe][sanctuary-def] version of [`Z.id`][].
```javascript
-> S.id(Function)(42)
+> S.id (Function) (42)
42
```
-
+#### `concat :: Semigroup a => a -> a -> a`
Curried version of [`Z.concat`][].
```javascript
-> S.concat('abc', 'def')
+> S.concat ('abc') ('def')
'abcdef'
-> S.concat([1, 2, 3], [4, 5, 6])
+> S.concat ([1, 2, 3]) ([4, 5, 6])
[1, 2, 3, 4, 5, 6]
-> S.concat({x: 1, y: 2}, {y: 3, z: 4})
+> S.concat ({x: 1, y: 2}) ({y: 3, z: 4})
{x: 1, y: 3, z: 4}
-> S.concat(S.Just([1, 2, 3]), S.Just([4, 5, 6]))
-Just([1, 2, 3, 4, 5, 6])
+> S.concat (S.Just ([1, 2, 3])) (S.Just ([4, 5, 6]))
+Just ([1, 2, 3, 4, 5, 6])
-> S.concat(Sum(18), Sum(24))
-Sum(42)
+> S.concat (Sum (18)) (Sum (24))
+Sum (42)
```
-
+#### `empty :: Monoid a => TypeRep a -> a`
[Type-safe][sanctuary-def] version of [`Z.empty`][].
```javascript
-> S.empty(String)
+> S.empty (String)
''
-> S.empty(Array)
+> S.empty (Array)
[]
-> S.empty(Object)
+> S.empty (Object)
{}
-> S.empty(Sum)
-Sum(0)
+> S.empty (Sum)
+Sum (0)
```
-
+#### `invert :: Group g => g -> g`
[Type-safe][sanctuary-def] version of [`Z.invert`][].
```javascript
-> S.invert(Sum(5))
-Sum(-5)
+> S.invert (Sum (5))
+Sum (-5)
+```
+
+#### `filter :: Filterable f => (a -> Boolean) -> f a -> f a`
+
+Curried version of [`Z.filter`][]. Discards every element which does not
+satisfy the predicate.
+
+See also [`reject`](#reject).
+
+```javascript
+> S.filter (S.odd) ([1, 2, 3])
+[1, 3]
+
+> S.filter (S.odd) ({x: 1, y: 2, z: 3})
+{x: 1, z: 3}
+
+> S.filter (S.odd) (S.Nothing)
+Nothing
+
+> S.filter (S.odd) (S.Just (0))
+Nothing
+
+> S.filter (S.odd) (S.Just (1))
+Just (1)
+```
+
+#### `reject :: Filterable f => (a -> Boolean) -> f a -> f a`
+
+Curried version of [`Z.reject`][]. Discards every element which satisfies
+the predicate.
+
+See also [`filter`](#filter).
+
+```javascript
+> S.reject (S.odd) ([1, 2, 3])
+[2]
+
+> S.reject (S.odd) ({x: 1, y: 2, z: 3})
+{y: 2}
+
+> S.reject (S.odd) (S.Nothing)
+Nothing
+
+> S.reject (S.odd) (S.Just (0))
+Just (0)
+
+> S.reject (S.odd) (S.Just (1))
+Nothing
+```
+
+#### `takeWhile :: Filterable f => (a -> Boolean) -> f a -> f a`
+
+Curried version of [`Z.takeWhile`][]. Discards the first element which
+does not satisfy the predicate, and all subsequent elements.
+
+See also [`dropWhile`](#dropWhile).
+
+```javascript
+> S.takeWhile (S.odd) ([3, 3, 3, 7, 6, 3, 5, 4])
+[3, 3, 3, 7]
+
+> S.takeWhile (S.even) ([3, 3, 3, 7, 6, 3, 5, 4])
+[]
```
-
+#### `dropWhile :: Filterable f => (a -> Boolean) -> f a -> f a`
+
+Curried version of [`Z.dropWhile`][]. Retains the first element which
+does not satisfy the predicate, and all subsequent elements.
+
+See also [`takeWhile`](#takeWhile).
+
+```javascript
+> S.dropWhile (S.odd) ([3, 3, 3, 7, 6, 3, 5, 4])
+[6, 3, 5, 4]
+
+> S.dropWhile (S.even) ([3, 3, 3, 7, 6, 3, 5, 4])
+[3, 3, 3, 7, 6, 3, 5, 4]
+```
+
+#### `map :: Functor f => (a -> b) -> f a -> f b`
Curried version of [`Z.map`][].
```javascript
-> S.map(Math.sqrt, [1, 4, 9])
+> S.map (Math.sqrt) ([1, 4, 9])
[1, 2, 3]
-> S.map(Math.sqrt, {x: 1, y: 4, z: 9})
+> S.map (Math.sqrt) ({x: 1, y: 4, z: 9})
{x: 1, y: 2, z: 3}
-> S.map(Math.sqrt, S.Just(9))
-Just(3)
+> S.map (Math.sqrt) (S.Just (9))
+Just (3)
-> S.map(Math.sqrt, S.Right(9))
-Right(3)
+> S.map (Math.sqrt) (S.Right (9))
+Right (3)
+
+> S.map (Math.sqrt) (S.Pair (99980001) (99980001))
+Pair (99980001) (9999)
```
Replacing `Functor f => f` with `Function x` produces the B combinator
@@ -589,65 +763,113 @@ from combinatory logic (i.e. [`compose`](#compose)):
(b -> c) -> (a -> b) -> (a -> c)
```javascript
-> S.map(Math.sqrt, S.add(1))(99)
+> S.map (Math.sqrt) (S.add (1)) (99)
10
```
-
+#### `flip :: Functor f => f (a -> b) -> a -> f b`
+
+Curried version of [`Z.flip`][]. Maps over the given functions, applying
+each to the given value.
+
+Replacing `Functor f => f` with `Function x` produces the C combinator
+from combinatory logic:
+
+ Functor f => f (a -> b) -> a -> f b
+ Function x (a -> b) -> a -> Function x b
+ Function x (a -> c) -> a -> Function x c
+ Function x (b -> c) -> b -> Function x c
+ Function a (b -> c) -> b -> Function a c
+ (a -> b -> c) -> b -> a -> c
+
+```javascript
+> S.flip (S.concat) ('!') ('foo')
+'foo!'
+
+> S.flip ([Math.floor, Math.ceil]) (1.5)
+[1, 2]
+
+> S.flip ({floor: Math.floor, ceil: Math.ceil}) (1.5)
+{floor: 1, ceil: 2}
+
+> S.flip (Cons (Math.floor) (Cons (Math.ceil) (Nil))) (1.5)
+Cons (1) (Cons (2) (Nil))
+```
+
+#### `bimap :: Bifunctor f => (a -> b) -> (c -> d) -> f a c -> f b d`
Curried version of [`Z.bimap`][].
```javascript
-> S.bimap(S.toUpper, Math.sqrt, S.Left('foo'))
-Left('FOO')
+> S.bimap (S.toUpper) (Math.sqrt) (S.Pair ('foo') (64))
+Pair ('FOO') (8)
+
+> S.bimap (S.toUpper) (Math.sqrt) (S.Left ('foo'))
+Left ('FOO')
-> S.bimap(S.toUpper, Math.sqrt, S.Right(64))
-Right(8)
+> S.bimap (S.toUpper) (Math.sqrt) (S.Right (64))
+Right (8)
```
-
+#### `mapLeft :: Bifunctor f => (a -> b) -> f a c -> f b c`
+
+Curried version of [`Z.mapLeft`][]. Maps the given function over the left
+side of a Bifunctor.
+
+```javascript
+> S.mapLeft (S.toUpper) (S.Pair ('foo') (64))
+Pair ('FOO') (64)
+
+> S.mapLeft (S.toUpper) (S.Left ('foo'))
+Left ('FOO')
+
+> S.mapLeft (S.toUpper) (S.Right (64))
+Right (64)
+```
+
+#### `promap :: Profunctor p => (a -> b) -> (c -> d) -> p b c -> p a d`
Curried version of [`Z.promap`][].
```javascript
-> S.promap(Math.abs, S.add(1), Math.sqrt)(-100)
+> S.promap (Math.abs) (S.add (1)) (Math.sqrt) (-100)
11
```
-
+#### `alt :: Alt f => f a -> f a -> f a`
Curried version of [`Z.alt`][].
```javascript
-> S.alt(S.Nothing, S.Just(1))
-Just(1)
+> S.alt (S.Nothing) (S.Just (1))
+Just (1)
-> S.alt(S.Just(2), S.Just(3))
-Just(2)
+> S.alt (S.Just (2)) (S.Just (3))
+Just (2)
-> S.alt(S.Left('X'), S.Right(1))
-Right(1)
+> S.alt (S.Left ('X')) (S.Right (1))
+Right (1)
-> S.alt(S.Right(2), S.Right(3))
-Right(2)
+> S.alt (S.Right (2)) (S.Right (3))
+Right (2)
```
-
+#### `zero :: Plus f => TypeRep f -> f a`
[Type-safe][sanctuary-def] version of [`Z.zero`][].
```javascript
-> S.zero(Array)
+> S.zero (Array)
[]
-> S.zero(Object)
+> S.zero (Object)
{}
-> S.zero(S.Maybe)
+> S.zero (S.Maybe)
Nothing
```
-
+#### `reduce :: Foldable f => (b -> a -> b) -> b -> f a -> b`
Takes a curried binary function, an initial value, and a [Foldable][],
and applies the function to the initial value and the Foldable's first
@@ -658,72 +880,72 @@ value if the Foldable is empty; the result of the final application
otherwise.
```javascript
-> S.reduce(S.add, 0, [1, 2, 3, 4, 5])
+> S.reduce (S.add) (0) ([1, 2, 3, 4, 5])
15
-> S.reduce(xs => x => [x].concat(xs), [], [1, 2, 3, 4, 5])
+> S.reduce (xs => x => S.prepend (x) (xs)) ([]) ([1, 2, 3, 4, 5])
[5, 4, 3, 2, 1]
```
-
+#### `traverse :: (Applicative f, Traversable t) => TypeRep f -> (a -> f b) -> t a -> f (t b)`
Curried version of [`Z.traverse`][].
```javascript
-> S.traverse(Array, S.words, S.Just('foo bar baz'))
-[Just('foo'), Just('bar'), Just('baz')]
+> S.traverse (Array) (S.words) (S.Just ('foo bar baz'))
+[Just ('foo'), Just ('bar'), Just ('baz')]
-> S.traverse(Array, S.words, S.Nothing)
+> S.traverse (Array) (S.words) (S.Nothing)
[Nothing]
-> S.traverse(S.Maybe, S.parseInt(16), ['A', 'B', 'C'])
-Just([10, 11, 12])
+> S.traverse (S.Maybe) (S.parseInt (16)) (['A', 'B', 'C'])
+Just ([10, 11, 12])
-> S.traverse(S.Maybe, S.parseInt(16), ['A', 'B', 'C', 'X'])
+> S.traverse (S.Maybe) (S.parseInt (16)) (['A', 'B', 'C', 'X'])
Nothing
-> S.traverse(S.Maybe, S.parseInt(16), {a: 'A', b: 'B', c: 'C'})
-Just({a: 10, b: 11, c: 12})
+> S.traverse (S.Maybe) (S.parseInt (16)) ({a: 'A', b: 'B', c: 'C'})
+Just ({a: 10, b: 11, c: 12})
-> S.traverse(S.Maybe, S.parseInt(16), {a: 'A', b: 'B', c: 'C', x: 'X'})
+> S.traverse (S.Maybe) (S.parseInt (16)) ({a: 'A', b: 'B', c: 'C', x: 'X'})
Nothing
```
-
+#### `sequence :: (Applicative f, Traversable t) => TypeRep f -> t (f a) -> f (t a)`
Curried version of [`Z.sequence`][]. Inverts the given `t (f a)`
to produce an `f (t a)`.
```javascript
-> S.sequence(Array, S.Just([1, 2, 3]))
-[Just(1), Just(2), Just(3)]
+> S.sequence (Array) (S.Just ([1, 2, 3]))
+[Just (1), Just (2), Just (3)]
-> S.sequence(S.Maybe, [S.Just(1), S.Just(2), S.Just(3)])
-Just([1, 2, 3])
+> S.sequence (S.Maybe) ([S.Just (1), S.Just (2), S.Just (3)])
+Just ([1, 2, 3])
-> S.sequence(S.Maybe, [S.Just(1), S.Just(2), S.Nothing])
+> S.sequence (S.Maybe) ([S.Just (1), S.Just (2), S.Nothing])
Nothing
-> S.sequence(S.Maybe, {a: S.Just(1), b: S.Just(2), c: S.Just(3)})
-Just({a: 1, b: 2, c: 3})
+> S.sequence (S.Maybe) ({a: S.Just (1), b: S.Just (2), c: S.Just (3)})
+Just ({a: 1, b: 2, c: 3})
-> S.sequence(S.Maybe, {a: S.Just(1), b: S.Just(2), c: S.Nothing})
+> S.sequence (S.Maybe) ({a: S.Just (1), b: S.Just (2), c: S.Nothing})
Nothing
```
-
+#### `ap :: Apply f => f (a -> b) -> f a -> f b`
Curried version of [`Z.ap`][].
```javascript
-> S.ap([Math.sqrt, x => x * x], [1, 4, 9, 16, 25])
+> S.ap ([Math.sqrt, x => x * x]) ([1, 4, 9, 16, 25])
[1, 2, 3, 4, 5, 1, 16, 81, 256, 625]
-> S.ap({x: Math.sqrt, y: S.add(1), z: S.sub(1)}, {w: 4, x: 4, y: 4})
+> S.ap ({x: Math.sqrt, y: S.add (1), z: S.sub (1)}) ({w: 4, x: 4, y: 4})
{x: 2, y: 5}
-> S.ap(S.Just(Math.sqrt), S.Just(64))
-Just(8)
+> S.ap (S.Just (Math.sqrt)) (S.Just (64))
+Just (8)
```
Replacing `Apply f => f` with `Function x` produces the S combinator
@@ -737,43 +959,43 @@ from combinatory logic:
(a -> b -> c) -> (a -> b) -> (a -> c)
```javascript
-> S.ap(s => n => s.slice(0, n), s => Math.ceil(s.length / 2))('Haskell')
+> S.ap (s => n => s.slice (0, n)) (s => Math.ceil (s.length / 2)) ('Haskell')
'Hask'
```
-
+#### `lift2 :: Apply f => (a -> b -> c) -> f a -> f b -> f c`
Promotes a curried binary function to a function which operates on two
[Apply][]s.
```javascript
-> S.lift2(S.add, S.Just(2), S.Just(3))
-Just(5)
+> S.lift2 (S.add) (S.Just (2)) (S.Just (3))
+Just (5)
-> S.lift2(S.add, S.Just(2), S.Nothing)
+> S.lift2 (S.add) (S.Just (2)) (S.Nothing)
Nothing
-> S.lift2(S.and, S.Just(true), S.Just(true))
-Just(true)
+> S.lift2 (S.and) (S.Just (true)) (S.Just (true))
+Just (true)
-> S.lift2(S.and, S.Just(true), S.Just(false))
-Just(false)
+> S.lift2 (S.and) (S.Just (true)) (S.Just (false))
+Just (false)
```
-
+#### `lift3 :: Apply f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d`
Promotes a curried ternary function to a function which operates on three
[Apply][]s.
```javascript
-> S.lift3(S.reduce, S.Just(S.add), S.Just(0), S.Just([1, 2, 3]))
-Just(6)
+> S.lift3 (S.reduce) (S.Just (S.add)) (S.Just (0)) (S.Just ([1, 2, 3]))
+Just (6)
-> S.lift3(S.reduce, S.Just(S.add), S.Just(0), S.Nothing)
+> S.lift3 (S.reduce) (S.Just (S.add)) (S.Just (0)) (S.Nothing)
Nothing
```
-
+#### `apFirst :: Apply f => f a -> f b -> f a`
Curried version of [`Z.apFirst`][]. Combines two effectful actions,
keeping only the result of the first. Equivalent to Haskell's `(<*)`
@@ -782,14 +1004,14 @@ function.
See also [`apSecond`](#apSecond).
```javascript
-> S.apFirst([1, 2], [3, 4])
+> S.apFirst ([1, 2]) ([3, 4])
[1, 1, 2, 2]
-> S.apFirst(S.Just(1), S.Just(2))
-Just(1)
+> S.apFirst (S.Just (1)) (S.Just (2))
+Just (1)
```
-
+#### `apSecond :: Apply f => f a -> f b -> f b`
Curried version of [`Z.apSecond`][]. Combines two effectful actions,
keeping only the result of the second. Equivalent to Haskell's `(*>)`
@@ -798,63 +1020,66 @@ function.
See also [`apFirst`](#apFirst).
```javascript
-> S.apSecond([1, 2], [3, 4])
+> S.apSecond ([1, 2]) ([3, 4])
[3, 4, 3, 4]
-> S.apSecond(S.Just(1), S.Just(2))
-Just(2)
+> S.apSecond (S.Just (1)) (S.Just (2))
+Just (2)
```
-
+#### `of :: Applicative f => TypeRep f -> a -> f a`
Curried version of [`Z.of`][].
```javascript
-> S.of(Array, 42)
+> S.of (Array) (42)
[42]
-> S.of(Function, 42)(null)
+> S.of (Function) (42) (null)
42
-> S.of(S.Maybe, 42)
-Just(42)
+> S.of (S.Maybe) (42)
+Just (42)
-> S.of(S.Either, 42)
-Right(42)
+> S.of (S.Either) (42)
+Right (42)
```
-
+#### `chain :: Chain m => (a -> m b) -> m a -> m b`
Curried version of [`Z.chain`][].
```javascript
-> S.chain(x => [x, x], [1, 2, 3])
+> S.chain (x => [x, x]) ([1, 2, 3])
[1, 1, 2, 2, 3, 3]
-> S.chain(n => s => s.slice(0, n), s => Math.ceil(s.length / 2))('slice')
+> S.chain (n => s => s.slice (0, n)) (s => Math.ceil (s.length / 2)) ('slice')
'sli'
-> S.chain(S.parseInt(10), S.Just('123'))
-Just(123)
+> S.chain (S.parseInt (10)) (S.Just ('123'))
+Just (123)
-> S.chain(S.parseInt(10), S.Just('XXX'))
+> S.chain (S.parseInt (10)) (S.Just ('XXX'))
Nothing
```
-
+#### `join :: Chain m => m (m a) -> m a`
[Type-safe][sanctuary-def] version of [`Z.join`][].
Removes one level of nesting from a nested monadic structure.
```javascript
-> S.join([[1], [2], [3]])
+> S.join ([[1], [2], [3]])
[1, 2, 3]
-> S.join([[[1, 2, 3]]])
+> S.join ([[[1, 2, 3]]])
[[1, 2, 3]]
-> S.join(S.Just(S.Just(1)))
-S.Just(1)
+> S.join (S.Just (S.Just (1)))
+Just (1)
+
+> S.join (S.Pair ('foo') (S.Pair ('bar') ('baz')))
+Pair ('foobar') ('baz')
```
Replacing `Chain m => m` with `Function x` produces the W combinator
@@ -865,656 +1090,332 @@ from combinatory logic:
(x -> x -> a) -> (x -> a)
```javascript
-> S.join(S.concat)('abc')
+> S.join (S.concat) ('abc')
'abcabc'
```
-
+#### `chainRec :: ChainRec m => TypeRep m -> (a -> m (Either a b)) -> a -> m b`
Performs a [`chain`](#chain)-like computation with constant stack usage.
Similar to [`Z.chainRec`][], but curried and more convenient due to the
use of the Either type to indicate completion (via a Right).
```javascript
-> S.chainRec(Array,
-. s => s.length === 2 ? S.map(S.Right, [s + '!', s + '?'])
-. : S.map(S.Left, [s + 'o', s + 'n']),
-. '')
+> S.chainRec (Array)
+. (s => s.length === 2 ? S.map (S.Right) ([s + '!', s + '?'])
+. : S.map (S.Left) ([s + 'o', s + 'n']))
+. ('')
['oo!', 'oo?', 'on!', 'on?', 'no!', 'no?', 'nn!', 'nn?']
```
-
+#### `extend :: Extend w => (w a -> b) -> w a -> w b`
Curried version of [`Z.extend`][].
```javascript
-> S.extend(S.joinWith(''), ['x', 'y', 'z'])
+> S.extend (S.joinWith ('')) (['x', 'y', 'z'])
['xyz', 'yz', 'z']
-```
-
-
-[Type-safe][sanctuary-def] version of [`Z.extract`][].
-
-
-
-[Type-safe][sanctuary-def] version of [`Z.contramap`][].
-
-```javascript
-> S.contramap(s => s.length, Math.sqrt)('Sanctuary')
-3
+> S.extend (f => f ([3, 4])) (S.reverse) ([1, 2])
+[4, 3, 2, 1]
```
-
+#### `duplicate :: Extend w => w a -> w (w a)`
-Curried version of [`Z.filter`][]. Filters its second argument in
-accordance with the given predicate.
-
-See also [`filterM`](#filterM).
+[Type-safe][sanctuary-def] version of [`Z.duplicate`][].
+Adds one level of nesting to a comonadic structure.
```javascript
-> S.filter(S.odd, [1, 2, 3, 4, 5])
-[1, 3, 5]
-```
-
-
+> S.duplicate (S.Just (1))
+Just (Just (1))
-Curried version of [`Z.filterM`][]. Filters its second argument in
-accordance with the given predicate.
+> S.duplicate ([1])
+[[1]]
-See also [`filter`](#filter).
-
-```javascript
-> S.filterM(S.odd, [1, 2, 3, 4, 5])
-[1, 3, 5]
+> S.duplicate ([1, 2, 3])
+[[1, 2, 3], [2, 3], [3]]
-> S.filterM(S.odd, S.Just(9))
-Just(9)
-
-> S.filterM(S.odd, S.Just(4))
-Nothing
+> S.duplicate (S.reverse) ([1, 2]) ([3, 4])
+[4, 3, 2, 1]
```
-
+#### `extract :: Comonad w => w a -> a`
-Discards the first inner value which does not satisfy the predicate, and
-all subsequent inner values.
+[Type-safe][sanctuary-def] version of [`Z.extract`][].
```javascript
-> S.takeWhile(S.odd, [3, 3, 3, 7, 6, 3, 5, 4])
-[3, 3, 3, 7]
-
-> S.takeWhile(S.even, [3, 3, 3, 7, 6, 3, 5, 4])
-[]
+> S.extract (S.Pair ('foo') ('bar'))
+'bar'
```
-
+#### `contramap :: Contravariant f => (b -> a) -> f a -> f b`
-Retains the first inner value which does not satisfy the predicate, and
-all subsequent inner values.
+[Type-safe][sanctuary-def] version of [`Z.contramap`][].
```javascript
-> S.dropWhile(S.odd, [3, 3, 3, 7, 6, 3, 5, 4])
-[6, 3, 5, 4]
-
-> S.dropWhile(S.even, [3, 3, 3, 7, 6, 3, 5, 4])
-[3, 3, 3, 7, 6, 3, 5, 4]
+> S.contramap (s => s.length) (Math.sqrt) ('Sanctuary')
+3
```
### Combinator
-
+#### `I :: a -> a`
The I combinator. Returns its argument. Equivalent to Haskell's `id`
function.
```javascript
-> S.I('foo')
+> S.I ('foo')
'foo'
```
-
+#### `K :: a -> b -> a`
The K combinator. Takes two values and returns the first. Equivalent to
Haskell's `const` function.
```javascript
-> S.K('foo', 'bar')
+> S.K ('foo') ('bar')
'foo'
-> S.map(S.K(42), S.range(0, 5))
+> S.map (S.K (42)) (S.range (0) (5))
[42, 42, 42, 42, 42]
```
-
-
-The A combinator. Takes a function and a value, and returns the result
-of applying the function to the value. Equivalent to Haskell's `($)`
-function.
-
-```javascript
-> S.A(S.add(1), 42)
-43
-
-> S.map(S.A(S.__, 100), [S.add(1), Math.sqrt])
-[101, 10]
-```
-
-
+#### `T :: a -> (a -> b) -> b`
The T ([thrush][]) combinator. Takes a value and a function, and returns
the result of applying the function to the value. Equivalent to Haskell's
`(&)` function.
```javascript
-> S.T(42, S.add(1))
+> S.T (42) (S.add (1))
43
-> S.map(S.T(100), [S.add(1), Math.sqrt])
+> S.map (S.T (100)) ([S.add (1), Math.sqrt])
[101, 10]
```
### Function
-
+#### `curry2 :: ((a, b) -> c) -> a -> b -> c`
Curries the given binary function.
```javascript
-> S.map(S.curry2(Math.pow)(10), [1, 2, 3])
-[10, 100, 1000]
-
-> S.map(S.curry2(Math.pow, 10), [1, 2, 3])
+> S.map (S.curry2 (Math.pow) (10)) ([1, 2, 3])
[10, 100, 1000]
```
-
+#### `curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d`
Curries the given ternary function.
```javascript
-> global.replaceString = S.curry3((what, replacement, string) =>
-. string.replace(what, replacement)
+> const replaceString = S.curry3 ((what, replacement, string) =>
+. string.replace (what, replacement)
. )
-replaceString
-> replaceString('banana')('orange')('banana icecream')
-'orange icecream'
-
-> replaceString('banana', 'orange', 'banana icecream')
+> replaceString ('banana') ('orange') ('banana icecream')
'orange icecream'
```
-
+#### `curry4 :: ((a, b, c, d) -> e) -> a -> b -> c -> d -> e`
Curries the given quaternary function.
```javascript
-> global.createRect = S.curry4((x, y, width, height) =>
+> const createRect = S.curry4 ((x, y, width, height) =>
. ({x, y, width, height})
. )
-createRect
-
-> createRect(0)(0)(10)(10)
-{x: 0, y: 0, width: 10, height: 10}
-> createRect(0, 0, 10, 10)
+> createRect (0) (0) (10) (10)
{x: 0, y: 0, width: 10, height: 10}
```
-
+#### `curry5 :: ((a, b, c, d, e) -> f) -> a -> b -> c -> d -> e -> f`
Curries the given quinary function.
```javascript
-> global.toUrl = S.curry5((protocol, creds, hostname, port, pathname) =>
+> const toUrl = S.curry5 ((protocol, creds, hostname, port, pathname) =>
. protocol + '//' +
-. S.maybe('', _ => _.username + ':' + _.password + '@', creds) +
+. S.maybe ('') (S.flip (S.concat) ('@')) (creds) +
. hostname +
-. S.maybe('', S.concat(':'), port) +
+. S.maybe ('') (S.concat (':')) (port) +
. pathname
. )
-toUrl
-
-> toUrl('https:')(S.Nothing)('example.com')(S.Just('443'))('/foo/bar')
-'https://example.com:443/foo/bar'
-
-> toUrl('https:', S.Nothing, 'example.com', S.Just('443'), '/foo/bar')
-'https://example.com:443/foo/bar'
-```
-
-
-
-Takes a curried binary function and two values, and returns the
-result of applying the function to the values in reverse order.
-
-This is the C combinator from combinatory logic.
-
-```javascript
-> S.flip(S.concat, 'foo', 'bar')
-'barfoo'
-```
-
-### Composition
-
-
-
-Curried version of [`Z.compose`][].
-
-When specialized to Function, `compose` composes two unary functions,
-from right to left (this is the B combinator from combinatory logic).
-
-The generalized type signature indicates that `compose` is compatible
-with any [Semigroupoid][].
-
-See also [`pipe`](#pipe).
-
-```javascript
-> S.compose(Math.sqrt, S.add(1))(99)
-10
-```
-
-
-
-Takes an array of functions assumed to be unary and a value of any type,
-and returns the result of applying the sequence of transformations to
-the initial value.
-
-In general terms, `pipe` performs left-to-right composition of an array
-of functions. `pipe([f, g, h], x)` is equivalent to `h(g(f(x)))`.
-
-```javascript
-> S.pipe([S.add(1), Math.sqrt, S.sub(1)], 99)
-9
-```
-
-
-
-Takes a binary function `f`, a unary function `g`, and two
-values `x` and `y`. Returns `f(g(x))(g(y))`.
-
-This is the P combinator from combinatory logic.
-
-```javascript
-> S.on(S.concat, S.reverse, [1, 2, 3], [4, 5, 6])
-[3, 2, 1, 6, 5, 4]
-```
-
-### Maybe type
-
-The Maybe type represents optional values: a value of type `Maybe a` is
-either a Just whose value is of type `a` or Nothing (with no value).
-
-The Maybe type satisfies the [Ord][], [Monoid][], [Monad][],
-[Alternative][], [Traversable][], and [Extend][] specifications.
-
-
-
-A [`UnaryType`][UnaryType] for use with [sanctuary-def][].
-
-
-
-The [type representative](#type-representatives) for the Maybe type.
-
-
-
-Nothing.
-
-```javascript
-> S.Nothing
-Nothing
-```
-
-
-
-Takes a value of any type and returns a Just with the given value.
-
-```javascript
-> S.Just(42)
-Just(42)
-```
-
-
-
-Maybe type identifier, `'sanctuary/Maybe'`.
-
-
-
-Returns Nothing.
-
-It is idiomatic to use [`empty`](#empty) rather than use this function
-directly.
-
-```javascript
-> S.empty(S.Maybe)
-Nothing
-```
-
-
-
-Takes a value of any type and returns a Just with the given value.
-
-It is idiomatic to use [`of`](#of) rather than use this function
-directly.
-
-```javascript
-> S.of(S.Maybe, 42)
-Just(42)
-```
-
-
-
-Returns Nothing.
-
-It is idiomatic to use [`zero`](#zero) rather than use this function
-directly.
-
-```javascript
-> S.zero(S.Maybe)
-Nothing
-```
-
-
-
-`true` if `this` is Nothing; `false` if `this` is a Just.
-
-```javascript
-> S.Nothing.isNothing
-true
-
-> S.Just(42).isNothing
-false
-```
-
-
-
-`true` if `this` is a Just; `false` if `this` is Nothing.
-
-```javascript
-> S.Just(42).isJust
-true
-
-> S.Nothing.isJust
-false
-```
-
-
-
-Returns the string representation of the Maybe.
-
-```javascript
-> S.toString(S.Nothing)
-'Nothing'
-
-> S.toString(S.Just([1, 2, 3]))
-'Just([1, 2, 3])'
-```
-
-
-
-Returns the string representation of the Maybe. This method is used by
-`util.inspect` and the REPL to format a Maybe for display.
-
-See also [`Maybe#toString`][].
-
-```javascript
-> S.Nothing.inspect()
-'Nothing'
-
-> S.Just([1, 2, 3]).inspect()
-'Just([1, 2, 3])'
-```
-
-
-
-Takes a value `m` of the same type and returns `true` if:
-
- - `this` and `m` are both Nothing; or
-
- - `this` and `m` are both Justs, and their values are equal according
- to [`Z.equals`][].
-
-It is idiomatic to use [`equals`](#equals) rather than use this method
-directly.
-
-```javascript
-> S.equals(S.Nothing, S.Nothing)
-true
-
-> S.equals(S.Just([1, 2, 3]), S.Just([1, 2, 3]))
-true
-
-> S.equals(S.Just([1, 2, 3]), S.Just([3, 2, 1]))
-false
-
-> S.equals(S.Just([1, 2, 3]), S.Nothing)
-false
-```
-
-
-
-Takes a value `m` of the same type and returns `true` if:
-
- - `this` is Nothing; or
-
- - `this` and `m` are both Justs and the value of `this` is less than
- or equal to the value of `m` according to [`Z.lte`][].
-
-It is idiomatic to use [`lte`](#lte) or [`lte_`](#lte_) rather than use
-this method directly.
-
-```javascript
-> S.lte_(S.Nothing, S.Nothing)
-true
-
-> S.lte_(S.Nothing, S.Just(0))
-true
-
-> S.lte_(S.Just(0), S.Nothing)
-false
-
-> S.lte_(S.Just(0), S.Just(1))
-true
-> S.lte_(S.Just(1), S.Just(0))
-false
+> toUrl ('https:') (S.Nothing) ('example.com') (S.Just ('443')) ('/foo/bar')
+'https://example.com:443/foo/bar'
```
-
+### Composition
-Returns the result of concatenating two Maybe values of the same type.
-`a` must have a [Semigroup][].
+#### `compose :: Semigroupoid s => s b c -> s a b -> s a c`
-If `this` is Nothing and the argument is Nothing, this method returns
-Nothing.
+Curried version of [`Z.compose`][].
-If `this` is a Just and the argument is a Just, this method returns a
-Just whose value is the result of concatenating this Just's value and
-the given Just's value.
+When specialized to Function, `compose` composes two unary functions,
+from right to left (this is the B combinator from combinatory logic).
-Otherwise, this method returns the Just.
+The generalized type signature indicates that `compose` is compatible
+with any [Semigroupoid][].
-It is idiomatic to use [`concat`](#concat) rather than use this method
-directly.
+See also [`pipe`](#pipe).
```javascript
-> S.concat(S.Nothing, S.Nothing)
-Nothing
+> S.compose (Math.sqrt) (S.add (1)) (99)
+10
+```
-> S.concat(S.Just([1, 2, 3]), S.Just([4, 5, 6]))
-Just([1, 2, 3, 4, 5, 6])
+#### `pipe :: Foldable f => f (Any -> Any) -> a -> b`
-> S.concat(S.Nothing, S.Just([1, 2, 3]))
-Just([1, 2, 3])
+Takes a sequence of functions assumed to be unary and a value of any
+type, and returns the result of applying the sequence of transformations
+to the initial value.
-> S.concat(S.Just([1, 2, 3]), S.Nothing)
-Just([1, 2, 3])
+In general terms, `pipe` performs left-to-right composition of a sequence
+of functions. `pipe ([f, g, h]) (x)` is equivalent to `h (g (f (x)))`.
+
+```javascript
+> S.pipe ([S.add (1), Math.sqrt, S.sub (1)]) (99)
+9
```
-
+#### `pipeK :: (Foldable f, Chain m) => f (Any -> m Any) -> m a -> m b`
-Takes a function and returns `this` if `this` is Nothing; otherwise
-it returns a Just whose value is the result of applying the function
-to this Just's value.
+Takes a sequence of functions assumed to be unary which return values
+with a [Chain][], and a value of that Chain, and returns the result
+of applying the sequence of transformations to the initial value.
-It is idiomatic to use [`map`](#map) rather than use this method
-directly.
+In general terms, `pipeK` performs left-to-right [Kleisli][] composition
+of an sequence of functions. `pipeK ([f, g, h]) (x)` is equivalent to
+`chain (h) (chain (g) (chain (f) (x)))`.
```javascript
-> S.map(Math.sqrt, S.Nothing)
-Nothing
-
-> S.map(Math.sqrt, S.Just(9))
-Just(3)
+> S.pipeK ([S.tail, S.tail, S.head]) (S.Just ([1, 2, 3, 4]))
+Just (3)
```
-
+#### `on :: (b -> b -> c) -> (a -> b) -> a -> a -> c`
-Takes a Maybe and returns Nothing unless `this` is a Just *and* the
-argument is a Just, in which case it returns a Just whose value is
-the result of applying the given Just's value to this Just's value.
+Takes a binary function `f`, a unary function `g`, and two
+values `x` and `y`. Returns `f (g (x)) (g (y))`.
-It is idiomatic to use [`ap`](#ap) rather than use this method directly.
+This is the P combinator from combinatory logic.
```javascript
-> S.ap(S.Nothing, S.Nothing)
-Nothing
-
-> S.ap(S.Nothing, S.Just(9))
-Nothing
+> S.on (S.concat) (S.reverse) ([1, 2, 3]) ([4, 5, 6])
+[3, 2, 1, 6, 5, 4]
+```
-> S.ap(S.Just(Math.sqrt), S.Nothing)
-Nothing
+### Pair type
-> S.ap(S.Just(Math.sqrt), S.Just(9))
-Just(3)
-```
+Pair is the canonical product type: a value of type `Pair a b` always
+contains exactly two values: one of type `a`; one of type `b`.
-
+The implementation is provided by [sanctuary-pair][].
-Takes a function and returns `this` if `this` is Nothing; otherwise
-it returns the result of applying the function to this Just's value.
+#### `PairType :: Type -> Type -> Type`
-It is idiomatic to use [`chain`](#chain) rather than use this method
-directly.
+A [`BinaryType`][BinaryType] for use with [sanctuary-def][].
-```javascript
-> S.chain(S.parseFloat, S.Nothing)
-Nothing
+#### `Pair :: a -> b -> Pair a b`
-> S.chain(S.parseFloat, S.Just('xxx'))
-Nothing
+Pair's sole data constructor. Additionally, it serves as the
+Pair [type representative][].
-> S.chain(S.parseFloat, S.Just('12.34'))
-Just(12.34)
+```javascript
+> S.Pair ('foo') (42)
+Pair ('foo') (42)
```
-
-
-Chooses between `this` and the other Maybe provided as an argument.
-Returns `this` if `this` is a Just; the other Maybe otherwise.
+#### `fst :: Pair a b -> a`
-It is idiomatic to use [`alt`](#alt) rather than use this method
-directly.
+`fst (Pair (x) (y))` is equivalent to `x`.
```javascript
-> S.alt(S.Nothing, S.Nothing)
-Nothing
+> S.fst (S.Pair ('foo') (42))
+'foo'
+```
-> S.alt(S.Nothing, S.Just(1))
-Just(1)
+#### `snd :: Pair a b -> b`
-> S.alt(S.Just(2), S.Nothing)
-Just(2)
+`snd (Pair (x) (y))` is equivalent to `y`.
-> S.alt(S.Just(3), S.Just(4))
-Just(3)
+```javascript
+> S.snd (S.Pair ('foo') (42))
+42
```
-
+#### `swap :: Pair a b -> Pair b a`
-Takes a function and an initial value of any type, and returns:
+`swap (Pair (x) (y))` is equivalent to `Pair (y) (x)`.
- - the initial value if `this` is Nothing; otherwise
+```javascript
+> S.swap (S.Pair ('foo') (42))
+Pair (42) ('foo')
+```
- - the result of applying the function to the initial value and this
- Just's value.
+### Maybe type
-It is idiomatic to use [`reduce`](#reduce) rather than use this method
-directly.
+The Maybe type represents optional values: a value of type `Maybe a` is
+either Nothing (the empty value) or a Just whose value is of type `a`.
-```javascript
-> S.reduce(S.curry2(Math.pow), 10, S.Nothing)
-10
+The implementation is provided by [sanctuary-maybe][].
-> S.reduce(S.curry2(Math.pow), 10, S.Just(3))
-1000
-```
+#### `MaybeType :: Type -> Type`
-
+A [`UnaryType`][UnaryType] for use with [sanctuary-def][].
-Takes the type representative of some [Applicative][] and a function
-which returns a value of that Applicative, and returns:
+#### `Maybe :: TypeRep Maybe`
- - the result of applying the type representative's [`of`][] function to
- `this` if `this` is Nothing; otherwise
+Maybe [type representative][].
- - the result of mapping [`Just`](#Just) over the result of applying the
- first function to this Just's value.
+#### `Nothing :: Maybe a`
-It is idiomatic to use [`traverse`](#traverse) rather than use this
-method directly.
+The empty value of type `Maybe a`.
```javascript
-> S.traverse(Array, S.words, S.Nothing)
-[Nothing]
-
-> S.traverse(Array, S.words, S.Just('foo bar baz'))
-[Just('foo'), Just('bar'), Just('baz')]
+> S.Nothing
+Nothing
```
-
+#### `Just :: a -> Maybe a`
-Takes a function and returns `this` if `this` is Nothing; otherwise
-it returns a Just whose value is the result of applying the function
-to `this`.
-
-It is idiomatic to use [`extend`](#extend) rather than use this method
-directly.
+Constructs a value of type `Maybe a` from a value of type `a`.
```javascript
-> S.extend(x => x.value + 1, S.Nothing)
-Nothing
-
-> S.extend(x => x.value + 1, S.Just(42))
-Just(43)
+> S.Just (42)
+Just (42)
```
-
+#### `isNothing :: Maybe a -> Boolean`
Returns `true` if the given Maybe is Nothing; `false` if it is a Just.
```javascript
-> S.isNothing(S.Nothing)
+> S.isNothing (S.Nothing)
true
-> S.isNothing(S.Just(42))
+> S.isNothing (S.Just (42))
false
```
-
+#### `isJust :: Maybe a -> Boolean`
Returns `true` if the given Maybe is a Just; `false` if it is Nothing.
```javascript
-> S.isJust(S.Just(42))
+> S.isJust (S.Just (42))
true
-> S.isJust(S.Nothing)
+> S.isJust (S.Nothing)
false
```
-
+#### `fromMaybe :: a -> Maybe a -> a`
Takes a default value and a Maybe, and returns the Maybe's value
if the Maybe is a Just; the default value otherwise.
@@ -1523,29 +1424,29 @@ See also [`fromMaybe_`](#fromMaybe_) and
[`maybeToNullable`](#maybeToNullable).
```javascript
-> S.fromMaybe(0, S.Just(42))
+> S.fromMaybe (0) (S.Just (42))
42
-> S.fromMaybe(0, S.Nothing)
+> S.fromMaybe (0) (S.Nothing)
0
```
-
+#### `fromMaybe_ :: (() -> a) -> Maybe a -> a`
Variant of [`fromMaybe`](#fromMaybe) which takes a thunk so the default
value is only computed if required.
```javascript
-> function fib(n) { return n <= 1 ? n : fib(n - 2) + fib(n - 1); }
+> function fib(n) { return n <= 1 ? n : fib (n - 2) + fib (n - 1); }
-> S.fromMaybe_(() => fib(30), S.Just(1000000))
+> S.fromMaybe_ (() => fib (30)) (S.Just (1000000))
1000000
-> S.fromMaybe_(() => fib(30), S.Nothing)
+> S.fromMaybe_ (() => fib (30)) (S.Nothing)
832040
```
-
+#### `maybeToNullable :: Maybe a -> Nullable a`
Returns the given Maybe's value if the Maybe is a Just; `null` otherwise.
[Nullable][] is defined in [sanctuary-def][].
@@ -1553,27 +1454,27 @@ Returns the given Maybe's value if the Maybe is a Just; `null` otherwise.
See also [`fromMaybe`](#fromMaybe).
```javascript
-> S.maybeToNullable(S.Just(42))
+> S.maybeToNullable (S.Just (42))
42
-> S.maybeToNullable(S.Nothing)
+> S.maybeToNullable (S.Nothing)
null
```
-
+#### `toMaybe :: a? -> Maybe a`
Takes a value and returns Nothing if the value is `null` or `undefined`;
Just the value otherwise.
```javascript
-> S.toMaybe(null)
+> S.toMaybe (null)
Nothing
-> S.toMaybe(42)
-Just(42)
+> S.toMaybe (42)
+Just (42)
```
-
+#### `maybe :: b -> (a -> b) -> Maybe a -> b`
Takes a value of any type, a function, and a Maybe. If the Maybe is
a Just, the return value is the result of applying the function to
@@ -1582,56 +1483,56 @@ the Just's value. Otherwise, the first argument is returned.
See also [`maybe_`](#maybe_).
```javascript
-> S.maybe(0, S.prop('length'), S.Just('refuge'))
+> S.maybe (0) (S.prop ('length')) (S.Just ('refuge'))
6
-> S.maybe(0, S.prop('length'), S.Nothing)
+> S.maybe (0) (S.prop ('length')) (S.Nothing)
0
```
-
+#### `maybe_ :: (() -> b) -> (a -> b) -> Maybe a -> b`
Variant of [`maybe`](#maybe) which takes a thunk so the default value
is only computed if required.
```javascript
-> function fib(n) { return n <= 1 ? n : fib(n - 2) + fib(n - 1); }
+> function fib(n) { return n <= 1 ? n : fib (n - 2) + fib (n - 1); }
-> S.maybe_(() => fib(30), Math.sqrt, S.Just(1000000))
+> S.maybe_ (() => fib (30)) (Math.sqrt) (S.Just (1000000))
1000
-> S.maybe_(() => fib(30), Math.sqrt, S.Nothing)
+> S.maybe_ (() => fib (30)) (Math.sqrt) (S.Nothing)
832040
```
-
+#### `justs :: (Filterable f, Functor f) => f (Maybe a) -> f a`
-Takes an array of Maybes and returns an array containing each Just's
-value. Equivalent to Haskell's `catMaybes` function.
+Discards each element which is Nothing, and unwraps each element which is
+a Just. Related to Haskell's `catMaybes` function.
See also [`lefts`](#lefts) and [`rights`](#rights).
```javascript
-> S.justs([S.Just('foo'), S.Nothing, S.Just('baz')])
+> S.justs ([S.Just ('foo'), S.Nothing, S.Just ('baz')])
['foo', 'baz']
```
-
-
-Takes a function and an array, applies the function to each element of
-the array, and returns an array of "successful" results. If the result of
-applying the function to an element of the array is Nothing, the result
-is discarded; if the result is a Just, the Just's value is included in
-the output array.
+#### `mapMaybe :: (Filterable f, Functor f) => (a -> Maybe b) -> f a -> f b`
-In general terms, `mapMaybe` filters an array while mapping over it.
+Takes a function and a structure, applies the function to each element
+of the structure, and returns the "successful" results. If the result of
+applying the function to an element is Nothing, the result is discarded;
+if the result is a Just, the Just's value is included.
```javascript
-> S.mapMaybe(S.head, [[], [1, 2, 3], [], [4, 5, 6], []])
+> S.mapMaybe (S.head) ([[], [1, 2, 3], [], [4, 5, 6], []])
[1, 4]
+
+> S.mapMaybe (S.head) ({x: [1, 2, 3], y: [], z: [4, 5, 6]})
+{x: 1, z: 4}
```
-
+#### `encase :: (a -> b) -> a -> Maybe b`
Takes a unary function `f` which may throw and a value `x` of any type,
and applies `f` to `x` inside a `try` block. If an exception is caught,
@@ -1641,22 +1542,22 @@ result of applying `f` to `x`.
See also [`encaseEither`](#encaseEither).
```javascript
-> S.encase(eval, '1 + 1')
-Just(2)
+> S.encase (eval) ('1 + 1')
+Just (2)
-> S.encase(eval, '1 +')
+> S.encase (eval) ('1 +')
Nothing
```
-
+#### `encase2 :: (a -> b -> c) -> a -> b -> Maybe c`
Binary version of [`encase`](#encase).
-
+#### `encase3 :: (a -> b -> c -> d) -> a -> b -> c -> Maybe d`
Ternary version of [`encase`](#encase).
-
+#### `maybeToEither :: a -> Maybe b -> Either a b`
Converts a Maybe to an Either. Nothing becomes a Left (containing the
first argument); a Just becomes a Right.
@@ -1664,11 +1565,11 @@ first argument); a Just becomes a Right.
See also [`eitherToMaybe`](#eitherToMaybe).
```javascript
-> S.maybeToEither('Expecting an integer', S.parseInt(10, 'xyz'))
-Left('Expecting an integer')
+> S.maybeToEither ('Expecting an integer') (S.parseInt (10) ('xyz'))
+Left ('Expecting an integer')
-> S.maybeToEither('Expecting an integer', S.parseInt(10, '42'))
-Right(42)
+> S.maybeToEither ('Expecting an integer') (S.parseInt (10) ('42'))
+Right (42)
```
### Either type
@@ -1677,406 +1578,96 @@ The Either type represents values with two possibilities: a value of type
`Either a b` is either a Left whose value is of type `a` or a Right whose
value is of type `b`.
-The Either type satisfies the [Ord][], [Semigroup][], [Monad][],
-[Alt][], [Traversable][], [Extend][], and [Bifunctor][] specifications.
+The implementation is provided by [sanctuary-either][].
-
+#### `EitherType :: Type -> Type -> Type`
A [`BinaryType`][BinaryType] for use with [sanctuary-def][].
-
-
-The [type representative](#type-representatives) for the Either type.
-
-
-
-Takes a value of any type and returns a Left with the given value.
-
-```javascript
-> S.Left('Cannot divide by zero')
-Left('Cannot divide by zero')
-```
-
-
-
-Takes a value of any type and returns a Right with the given value.
-
-```javascript
-> S.Right(42)
-Right(42)
-```
-
-
-
-Either type identifier, `'sanctuary/Either'`.
-
-
-
-Takes a value of any type and returns a Right with the given value.
-
-It is idiomatic to use [`of`](#of) rather than use this function
-directly.
-
-```javascript
-> S.of(S.Either, 42)
-Right(42)
-```
-
-
-
-`true` if `this` is a Left; `false` if `this` is a Right.
-
-```javascript
-> S.Left('Cannot divide by zero').isLeft
-true
-
-> S.Right(42).isLeft
-false
-```
-
-
-
-`true` if `this` is a Right; `false` if `this` is a Left.
-
-```javascript
-> S.Right(42).isRight
-true
-
-> S.Left('Cannot divide by zero').isRight
-false
-```
-
-
-
-Returns the string representation of the Either.
-
-```javascript
-> S.toString(S.Left('Cannot divide by zero'))
-'Left("Cannot divide by zero")'
-
-> S.toString(S.Right([1, 2, 3]))
-'Right([1, 2, 3])'
-```
-
-
-
-Returns the string representation of the Either. This method is used by
-`util.inspect` and the REPL to format a Either for display.
-
-See also [`Either#toString`][].
-
-```javascript
-> S.Left('Cannot divide by zero').inspect()
-'Left("Cannot divide by zero")'
-
-> S.Right([1, 2, 3]).inspect()
-'Right([1, 2, 3])'
-```
-
-
-
-Takes a value `e` of the same type and returns `true` if:
-
- - `this` and `e` are both Lefts or both Rights, and their values are
- equal according to [`Z.equals`][].
-
-It is idiomatic to use [`equals`](#equals) rather than use this method
-directly.
-
-```javascript
-> S.equals(S.Right([1, 2, 3]), S.Right([1, 2, 3]))
-true
-
-> S.equals(S.Right([1, 2, 3]), S.Left([1, 2, 3]))
-false
-```
-
-
-
-Takes a value `e` of the same type and returns `true` if:
-
- - `this` is a Left and `e` is a Right; or
-
- - `this` and `e` are both Lefts or both Rights, and the value of `this`
- is less than or equal to the value of `e` according to [`Z.lte`][].
-
-It is idiomatic to use [`lte`](#lte) or [`lte_`](#lte_) rather than use
-this method directly.
-
-```javascript
-> S.lte_(S.Left(10), S.Right(0))
-true
-
-> S.lte_(S.Right(0), S.Left(10))
-false
-
-> S.lte_(S.Right(0), S.Right(1))
-true
-
-> S.lte_(S.Right(1), S.Right(0))
-false
-```
-
-
-
-Returns the result of concatenating two Either values of the same type.
-`a` must have a [Semigroup][], as must `b`.
-
-If `this` is a Left and the argument is a Left, this method returns a
-Left whose value is the result of concatenating this Left's value and
-the given Left's value.
-
-If `this` is a Right and the argument is a Right, this method returns a
-Right whose value is the result of concatenating this Right's value and
-the given Right's value.
-
-Otherwise, this method returns the Right.
-
-It is idiomatic to use [`concat`](#concat) rather than use this method
-directly.
-
-```javascript
-> S.concat(S.Left('abc'), S.Left('def'))
-Left('abcdef')
-
-> S.concat(S.Right([1, 2, 3]), S.Right([4, 5, 6]))
-Right([1, 2, 3, 4, 5, 6])
-
-> S.concat(S.Left('abc'), S.Right([1, 2, 3]))
-Right([1, 2, 3])
-
-> S.concat(S.Right([1, 2, 3]), S.Left('abc'))
-Right([1, 2, 3])
-```
-
-
-
-Takes a function and returns `this` if `this` is a Left; otherwise it
-returns a Right whose value is the result of applying the function to
-this Right's value.
-
-It is idiomatic to use [`map`](#map) rather than use this method
-directly.
-
-See also [`Either#fantasy-land/bimap`][].
-
-```javascript
-> S.map(Math.sqrt, S.Left('Cannot divide by zero'))
-Left('Cannot divide by zero')
-
-> S.map(Math.sqrt, S.Right(9))
-Right(3)
-```
-
-
-
-Takes two functions and returns:
-
- - a Left whose value is the result of applying the first function
- to this Left's value if `this` is a Left; otherwise
-
- - a Right whose value is the result of applying the second function
- to this Right's value.
-
-Similar to [`Either#fantasy-land/map`][], but supports mapping over the
-left side as well as the right side.
-
-It is idiomatic to use [`bimap`](#bimap) rather than use this method
-directly.
-
-```javascript
-> S.bimap(S.toUpper, S.add(1), S.Left('abc'))
-Left('ABC')
-
-> S.bimap(S.toUpper, S.add(1), S.Right(42))
-Right(43)
-```
-
-
-
-Takes an Either and returns a Left unless `this` is a Right *and* the
-argument is a Right, in which case it returns a Right whose value is
-the result of applying the given Right's value to this Right's value.
-
-It is idiomatic to use [`ap`](#ap) rather than use this method directly.
-
-```javascript
-> S.ap(S.Left('No such function'), S.Left('Cannot divide by zero'))
-Left('No such function')
-
-> S.ap(S.Left('No such function'), S.Right(9))
-Left('No such function')
-
-> S.ap(S.Right(Math.sqrt), S.Left('Cannot divide by zero'))
-Left('Cannot divide by zero')
-
-> S.ap(S.Right(Math.sqrt), S.Right(9))
-Right(3)
-```
-
-
-
-Takes a function and returns `this` if `this` is a Left; otherwise
-it returns the result of applying the function to this Right's value.
-
-It is idiomatic to use [`chain`](#chain) rather than use this method
-directly.
-
-```javascript
-> global.sqrt = n =>
-. n < 0 ? S.Left('Cannot represent square root of negative number')
-. : S.Right(Math.sqrt(n))
-sqrt
-
-> S.chain(sqrt, S.Left('Cannot divide by zero'))
-Left('Cannot divide by zero')
-
-> S.chain(sqrt, S.Right(-1))
-Left('Cannot represent square root of negative number')
-
-> S.chain(sqrt, S.Right(25))
-Right(5)
-```
-
-
-
-Chooses between `this` and the other Either provided as an argument.
-Returns `this` if `this` is a Right; the other Either otherwise.
-
-It is idiomatic to use [`alt`](#alt) rather than use this method
-directly.
-
-```javascript
-> S.alt(S.Left('A'), S.Left('B'))
-Left('B')
-
-> S.alt(S.Left('C'), S.Right(1))
-Right(1)
-
-> S.alt(S.Right(2), S.Left('D'))
-Right(2)
-
-> S.alt(S.Right(3), S.Right(4))
-Right(3)
-```
-
-
-
-Takes a function and an initial value of any type, and returns:
-
- - the initial value if `this` is a Left; otherwise
-
- - the result of applying the function to the initial value and this
- Right's value.
-
-It is idiomatic to use [`reduce`](#reduce) rather than use this method
-directly.
-
-```javascript
-> S.reduce(S.curry2(Math.pow), 10, S.Left('Cannot divide by zero'))
-10
-
-> S.reduce(S.curry2(Math.pow), 10, S.Right(3))
-1000
-```
-
-
-
-Takes the type representative of some [Applicative][] and a function
-which returns a value of that Applicative, and returns:
+#### `Either :: TypeRep Either`
- - the result of applying the type representative's [`of`][] function to
- `this` if `this` is a Left; otherwise
+Either [type representative][].
- - the result of mapping [`Right`](#Right) over the result of applying
- the first function to this Right's value.
+#### `Left :: a -> Either a b`
-It is idiomatic to use [`traverse`](#traverse) rather than use this
-method directly.
+Constructs a value of type `Either a b` from a value of type `a`.
```javascript
-> S.traverse(Array, S.words, S.Left('Request failed'))
-[Left('Request failed')]
-
-> S.traverse(Array, S.words, S.Right('foo bar baz'))
-[Right('foo'), Right('bar'), Right('baz')]
+> S.Left ('Cannot divide by zero')
+Left ('Cannot divide by zero')
```
-
-
-Takes a function and returns `this` if `this` is a Left; otherwise it
-returns a Right whose value is the result of applying the function to
-`this`.
+#### `Right :: b -> Either a b`
-It is idiomatic to use [`extend`](#extend) rather than use this method
-directly.
+Constructs a value of type `Either a b` from a value of type `b`.
```javascript
-> S.extend(x => x.value + 1, S.Left('Cannot divide by zero'))
-Left('Cannot divide by zero')
-
-> S.extend(x => x.value + 1, S.Right(42))
-Right(43)
+> S.Right (42)
+Right (42)
```
-
+#### `isLeft :: Either a b -> Boolean`
Returns `true` if the given Either is a Left; `false` if it is a Right.
```javascript
-> S.isLeft(S.Left('Cannot divide by zero'))
+> S.isLeft (S.Left ('Cannot divide by zero'))
true
-> S.isLeft(S.Right(42))
+> S.isLeft (S.Right (42))
false
```
-
+#### `isRight :: Either a b -> Boolean`
Returns `true` if the given Either is a Right; `false` if it is a Left.
```javascript
-> S.isRight(S.Right(42))
+> S.isRight (S.Right (42))
true
-> S.isRight(S.Left('Cannot divide by zero'))
+> S.isRight (S.Left ('Cannot divide by zero'))
false
```
-
+#### `fromEither :: b -> Either a b -> b`
Takes a default value and an Either, and returns the Right value
if the Either is a Right; the default value otherwise.
```javascript
-> S.fromEither(0, S.Right(42))
+> S.fromEither (0) (S.Right (42))
42
-> S.fromEither(0, S.Left(42))
+> S.fromEither (0) (S.Left (42))
0
```
-
+#### `toEither :: a -> b? -> Either a b`
Converts an arbitrary value to an Either: a Left if the value is `null`
or `undefined`; a Right otherwise. The first argument specifies the
value of the Left in the "failure" case.
```javascript
-> S.toEither('XYZ', null)
-Left('XYZ')
+> S.toEither ('XYZ') (null)
+Left ('XYZ')
-> S.toEither('XYZ', 'ABC')
-Right('ABC')
+> S.toEither ('XYZ') ('ABC')
+Right ('ABC')
-> S.map(S.prop('0'), S.toEither('Invalid protocol', 'ftp://example.com/'.match(/^https?:/)))
-Left('Invalid protocol')
+> S.map (S.prop ('0'))
+. (S.toEither ('Invalid protocol')
+. ('ftp://example.com/'.match (/^https?:/)))
+Left ('Invalid protocol')
-> S.map(S.prop('0'), S.toEither('Invalid protocol', 'https://example.com/'.match(/^https?:/)))
-Right('https:')
+> S.map (S.prop ('0'))
+. (S.toEither ('Invalid protocol')
+. ('https://example.com/'.match (/^https?:/)))
+Right ('https:')
```
-
+#### `either :: (a -> c) -> (b -> c) -> Either a b -> c`
Takes two functions and an Either, and returns the result of
applying the first function to the Left's value, if the Either
@@ -2084,51 +1675,51 @@ is a Left, or the result of applying the second function to the
Right's value, if the Either is a Right.
```javascript
-> S.either(S.toUpper, S.toString, S.Left('Cannot divide by zero'))
+> S.either (S.toUpper) (S.show) (S.Left ('Cannot divide by zero'))
'CANNOT DIVIDE BY ZERO'
-> S.either(S.toUpper, S.toString, S.Right(42))
+> S.either (S.toUpper) (S.show) (S.Right (42))
'42'
```
-
+#### `lefts :: (Filterable f, Functor f) => f (Either a b) -> f a`
-Takes an array of Eithers and returns an array containing each Left's
-value.
+Discards each element which is a Right, and unwraps each element which is
+a Left.
See also [`rights`](#rights).
```javascript
-> S.lefts([S.Right(20), S.Left('foo'), S.Right(10), S.Left('bar')])
+> S.lefts ([S.Right (20), S.Left ('foo'), S.Right (10), S.Left ('bar')])
['foo', 'bar']
```
-
+#### `rights :: (Filterable f, Functor f) => f (Either a b) -> f b`
-Takes an array of Eithers and returns an array containing each Right's
-value.
+Discards each element which is a Left, and unwraps each element which is
+a Right.
See also [`lefts`](#lefts).
```javascript
-> S.rights([S.Right(20), S.Left('foo'), S.Right(10), S.Left('bar')])
+> S.rights ([S.Right (20), S.Left ('foo'), S.Right (10), S.Left ('bar')])
[20, 10]
```
-
+#### `tagBy :: (a -> Boolean) -> a -> Either a a`
Takes a predicate and a value, and returns a Right of the value if it
satisfies the predicate; a Left of the value otherwise.
```javascript
-> S.tagBy(S.odd, 0)
-Left(0)
+> S.tagBy (S.odd) (0)
+Left (0)
-> S.tagBy(S.odd, 1)
-Right(1)
+> S.tagBy (S.odd) (1)
+Right (1)
```
-
+#### `encaseEither :: (Error -> l) -> (a -> r) -> a -> Either l r`
Takes two unary functions, `f` and `g`, the second of which may throw,
and a value `x` of any type. Applies `g` to `x` inside a `try` block.
@@ -2139,25 +1730,25 @@ value is a Right containing the result of applying `g` to `x`.
See also [`encase`](#encase).
```javascript
-> S.encaseEither(S.I, JSON.parse, '["foo","bar","baz"]')
-Right(['foo', 'bar', 'baz'])
+> S.encaseEither (S.I) (JSON.parse) ('["foo","bar","baz"]')
+Right (['foo', 'bar', 'baz'])
-> S.encaseEither(S.I, JSON.parse, '[')
-Left(new SyntaxError('Unexpected end of JSON input'))
+> S.encaseEither (S.I) (JSON.parse) ('[')
+Left (new SyntaxError ('Unexpected end of JSON input'))
-> S.encaseEither(S.prop('message'), JSON.parse, '[')
-Left('Unexpected end of JSON input')
+> S.encaseEither (S.prop ('message')) (JSON.parse) ('[')
+Left ('Unexpected end of JSON input')
```
-
+#### `encaseEither2 :: (Error -> l) -> (a -> b -> r) -> a -> b -> Either l r`
Binary version of [`encaseEither`](#encaseEither).
-
+#### `encaseEither3 :: (Error -> l) -> (a -> b -> c -> r) -> a -> b -> c -> Either l r`
Ternary version of [`encaseEither`](#encaseEither).
-
+#### `eitherToMaybe :: Either a b -> Maybe b`
Converts an Either to a Maybe. A Left becomes Nothing; a Right becomes
a Just.
@@ -2165,66 +1756,66 @@ a Just.
See also [`maybeToEither`](#maybeToEither).
```javascript
-> S.eitherToMaybe(S.Left('Cannot divide by zero'))
+> S.eitherToMaybe (S.Left ('Cannot divide by zero'))
Nothing
-> S.eitherToMaybe(S.Right(42))
-Just(42)
+> S.eitherToMaybe (S.Right (42))
+Just (42)
```
### Logic
-
+#### `and :: Boolean -> Boolean -> Boolean`
Boolean "and".
```javascript
-> S.and(false, false)
+> S.and (false) (false)
false
-> S.and(false, true)
+> S.and (false) (true)
false
-> S.and(true, false)
+> S.and (true) (false)
false
-> S.and(true, true)
+> S.and (true) (true)
true
```
-
+#### `or :: Boolean -> Boolean -> Boolean`
Boolean "or".
```javascript
-> S.or(false, false)
+> S.or (false) (false)
false
-> S.or(false, true)
+> S.or (false) (true)
true
-> S.or(true, false)
+> S.or (true) (false)
true
-> S.or(true, true)
+> S.or (true) (true)
true
```
-
+#### `not :: Boolean -> Boolean`
Boolean "not".
See also [`complement`](#complement).
```javascript
-> S.not(false)
+> S.not (false)
true
-> S.not(true)
+> S.not (true)
false
```
-
+#### `complement :: (a -> Boolean) -> a -> Boolean`
Takes a unary predicate and a value of any type, and returns the logical
negation of applying the predicate to the value.
@@ -2232,14 +1823,14 @@ negation of applying the predicate to the value.
See also [`not`](#not).
```javascript
-> Number.isInteger(42)
+> Number.isInteger (42)
true
-> S.complement(Number.isInteger, 42)
+> S.complement (Number.isInteger) (42)
false
```
-
+#### `ifElse :: (a -> Boolean) -> (a -> b) -> (a -> b) -> a -> b`
Takes a unary predicate, a unary "if" function, a unary "else"
function, and a value of any type, and returns the result of
@@ -2250,14 +1841,14 @@ value otherwise.
See also [`when`](#when) and [`unless`](#unless).
```javascript
-> S.ifElse(x => x < 0, Math.abs, Math.sqrt, -1)
+> S.ifElse (x => x < 0) (Math.abs) (Math.sqrt) (-1)
1
-> S.ifElse(x => x < 0, Math.abs, Math.sqrt, 16)
+> S.ifElse (x => x < 0) (Math.abs) (Math.sqrt) (16)
4
```
-
+#### `when :: (a -> Boolean) -> (a -> a) -> a -> a`
Takes a unary predicate, a unary function, and a value of any type, and
returns the result of applying the function to the value if the value
@@ -2266,14 +1857,14 @@ satisfies the predicate; the value otherwise.
See also [`unless`](#unless) and [`ifElse`](#ifElse).
```javascript
-> S.when(x => x >= 0, Math.sqrt, 16)
+> S.when (x => x >= 0) (Math.sqrt) (16)
4
-> S.when(x => x >= 0, Math.sqrt, -1)
+> S.when (x => x >= 0) (Math.sqrt) (-1)
-1
```
-
+#### `unless :: (a -> Boolean) -> (a -> a) -> a -> a`
Takes a unary predicate, a unary function, and a value of any type, and
returns the result of applying the function to the value if the value
@@ -2282,14 +1873,14 @@ does not satisfy the predicate; the value otherwise.
See also [`when`](#when) and [`ifElse`](#ifElse).
```javascript
-> S.unless(x => x < 0, Math.sqrt, 16)
+> S.unless (x => x < 0) (Math.sqrt) (16)
4
-> S.unless(x => x < 0, Math.sqrt, -1)
+> S.unless (x => x < 0) (Math.sqrt) (-1)
-1
```
-
+#### `allPass :: Foldable f => f (a -> Boolean) -> a -> Boolean`
Takes a structure containing zero or more predicates, and a value
of any type. Returns `true` [iff][] the value satisfies all of the
@@ -2297,14 +1888,14 @@ predicates. None of the subsequent predicates will be applied after
the first predicate not satisfied.
```javascript
-> S.allPass([S.test(/q/), S.test(/u/), S.test(/i/)], 'quiessence')
+> S.allPass ([S.test (/q/), S.test (/u/), S.test (/i/)]) ('quiessence')
true
-> S.allPass([S.test(/q/), S.test(/u/), S.test(/i/)], 'fissiparous')
+> S.allPass ([S.test (/q/), S.test (/u/), S.test (/i/)]) ('fissiparous')
false
```
-
+#### `anyPass :: Foldable f => f (a -> Boolean) -> a -> Boolean`
Takes a structure containing zero or more predicates, and a value
of any type. Returns `true` [iff][] the value satisfies any of the
@@ -2312,275 +1903,256 @@ predicates. None of the subsequent predicates will be applied after
the first predicate satisfied.
```javascript
-> S.anyPass([S.test(/q/), S.test(/u/), S.test(/i/)], 'incandescent')
+> S.anyPass ([S.test (/q/), S.test (/u/), S.test (/i/)]) ('incandescent')
true
-> S.anyPass([S.test(/q/), S.test(/u/), S.test(/i/)], 'empathy')
+> S.anyPass ([S.test (/q/), S.test (/u/), S.test (/i/)]) ('empathy')
false
```
-### List
-
-The List type constructor enables type signatures to describe ad hoc
-polymorphic functions which operate on either [`Array`][$.Array] or
-[`String`][$.String] values.
-
-Mental gymnastics are required to treat arrays and strings similarly.
-`[1, 2, 3]` is a list containing `1`, `2`, and `3`. `'abc'` is a list
-containing `'a'`, `'b'`, and `'c'`. But what is the type of `'a'`?
-`String`, since JavaScript has no Char type! Thus:
-
- 'abc' :: String, List String, List (List String), ...
-
-Every member of `String` is also a member of `List String`!
+### Array
-
+#### `slice :: Integer -> Integer -> Array a -> Maybe (Array a)`
-Returns Just a list containing the elements from the supplied list
-from a beginning index (inclusive) to an end index (exclusive).
-Returns Nothing unless the start interval is less than or equal to
-the end interval, and the list contains both (half-open) intervals.
-Accepts negative indices, which indicate an offset from the end of
-the list.
+Takes a start index `i`, an end index `j`, and an array, and returns
+Just the `[i,j)` slice of the array if possible; Nothing otherwise.
+A negative index represents an offset from the length of the array.
See also [`take`](#take), [`drop`](#drop), [`takeLast`](#takeLast),
and [`dropLast`](#dropLast).
```javascript
-> S.slice(1, 3, ['a', 'b', 'c', 'd', 'e'])
-Just(['b', 'c'])
+> S.slice (1) (3) (['a', 'b', 'c', 'd', 'e'])
+Just (['b', 'c'])
-> S.slice(-3, -1, ['a', 'b', 'c', 'd', 'e'])
-Just(['c', 'd'])
+> S.slice (-3) (-1) (['a', 'b', 'c', 'd', 'e'])
+Just (['c', 'd'])
-> S.slice(1, 6, ['a', 'b', 'c', 'd', 'e'])
+> S.slice (1) (6) (['a', 'b', 'c', 'd', 'e'])
Nothing
-
-> S.slice(2, 6, 'banana')
-Just('nana')
```
-
+#### `at :: Integer -> Array a -> Maybe a`
-Takes an index and a list and returns Just the element of the list at
-the index if the index is within the list's bounds; Nothing otherwise.
-A negative index represents an offset from the length of the list.
+Returns Just the element of the given array at the specified index if
+the index is within the array's bounds; Nothing otherwise. A negative
+index represents an offset from the length of the array.
```javascript
-> S.at(2, ['a', 'b', 'c', 'd', 'e'])
-Just('c')
+> S.at (2) (['a', 'b', 'c', 'd', 'e'])
+Just ('c')
-> S.at(5, ['a', 'b', 'c', 'd', 'e'])
+> S.at (5) (['a', 'b', 'c', 'd', 'e'])
Nothing
-> S.at(-2, ['a', 'b', 'c', 'd', 'e'])
-Just('d')
+> S.at (-2) (['a', 'b', 'c', 'd', 'e'])
+Just ('d')
```
-
+#### `head :: Array a -> Maybe a`
-Takes a list and returns Just the first element of the list if the
-list contains at least one element; Nothing if the list is empty.
+Returns Just the first element of the given array if the array contains
+at least one element; Nothing otherwise.
```javascript
-> S.head([1, 2, 3])
-Just(1)
+> S.head ([1, 2, 3])
+Just (1)
-> S.head([])
+> S.head ([])
Nothing
```
-
+#### `last :: Array a -> Maybe a`
-Takes a list and returns Just the last element of the list if the
-list contains at least one element; Nothing if the list is empty.
+Returns Just the last element of the given array if the array contains
+at least one element; Nothing otherwise.
```javascript
-> S.last([1, 2, 3])
-Just(3)
+> S.last ([1, 2, 3])
+Just (3)
-> S.last([])
+> S.last ([])
Nothing
```
-
+#### `tail :: Array a -> Maybe (Array a)`
-Takes a list and returns Just a list containing all but the first
-of the list's elements if the list contains at least one element;
-Nothing if the list is empty.
+Returns Just all but the first of the given array's elements if the
+array contains at least one element; Nothing otherwise.
```javascript
-> S.tail([1, 2, 3])
-Just([2, 3])
+> S.tail ([1, 2, 3])
+Just ([2, 3])
-> S.tail([])
+> S.tail ([])
Nothing
```
-
+#### `init :: Array a -> Maybe (Array a)`
-Takes a list and returns Just a list containing all but the last
-of the list's elements if the list contains at least one element;
-Nothing if the list is empty.
+Returns Just all but the last of the given array's elements if the
+array contains at least one element; Nothing otherwise.
```javascript
-> S.init([1, 2, 3])
-Just([1, 2])
+> S.init ([1, 2, 3])
+Just ([1, 2])
-> S.init([])
+> S.init ([])
Nothing
```
-
+#### `take :: Integer -> Array a -> Maybe (Array a)`
-Returns Just the first N elements of the given collection if N is
-greater than or equal to zero and less than or equal to the length
-of the collection; Nothing otherwise.
+Returns Just the first N elements of the given array if N is greater
+than or equal to zero and less than or equal to the length of the array;
+Nothing otherwise.
```javascript
-> S.take(2, ['a', 'b', 'c', 'd', 'e'])
-Just(['a', 'b'])
+> S.take (2) (['a', 'b', 'c', 'd', 'e'])
+Just (['a', 'b'])
-> S.take(4, 'abcdefg')
-Just('abcd')
+> S.take (5) (['a', 'b', 'c', 'd', 'e'])
+Just (['a', 'b', 'c', 'd', 'e'])
-> S.take(4, ['a', 'b', 'c'])
+> S.take (6) (['a', 'b', 'c', 'd', 'e'])
Nothing
```
-
+#### `takeLast :: Integer -> Array a -> Maybe (Array a)`
-Returns Just the last N elements of the given collection if N is
-greater than or equal to zero and less than or equal to the length
-of the collection; Nothing otherwise.
+Returns Just the last N elements of the given array if N is greater
+than or equal to zero and less than or equal to the length of the array;
+Nothing otherwise.
```javascript
-> S.takeLast(2, ['a', 'b', 'c', 'd', 'e'])
-Just(['d', 'e'])
+> S.takeLast (2) (['a', 'b', 'c', 'd', 'e'])
+Just (['d', 'e'])
-> S.takeLast(4, 'abcdefg')
-Just('defg')
+> S.takeLast (5) (['a', 'b', 'c', 'd', 'e'])
+Just (['a', 'b', 'c', 'd', 'e'])
-> S.takeLast(4, ['a', 'b', 'c'])
+> S.takeLast (6) (['a', 'b', 'c', 'd', 'e'])
Nothing
```
-
+#### `drop :: Integer -> Array a -> Maybe (Array a)`
-Returns Just all but the first N elements of the given collection
-if N is greater than or equal to zero and less than or equal to the
-length of the collection; Nothing otherwise.
+Returns Just all but the first N elements of the given array if N is
+greater than or equal to zero and less than or equal to the length of
+the array; Nothing otherwise.
```javascript
-> S.drop(2, ['a', 'b', 'c', 'd', 'e'])
-Just(['c', 'd', 'e'])
+> S.drop (2) (['a', 'b', 'c', 'd', 'e'])
+Just (['c', 'd', 'e'])
-> S.drop(4, 'abcdefg')
-Just('efg')
+> S.drop (5) (['a', 'b', 'c', 'd', 'e'])
+Just ([])
-> S.drop(4, 'abc')
+> S.drop (6) (['a', 'b', 'c', 'd', 'e'])
Nothing
```
-
+#### `dropLast :: Integer -> Array a -> Maybe (Array a)`
-Returns Just all but the last N elements of the given collection
-if N is greater than or equal to zero and less than or equal to the
-length of the collection; Nothing otherwise.
+Returns Just all but the last N elements of the given array if N is
+greater than or equal to zero and less than or equal to the length of
+the array; Nothing otherwise.
```javascript
-> S.dropLast(2, ['a', 'b', 'c', 'd', 'e'])
-Just(['a', 'b', 'c'])
+> S.dropLast (2) (['a', 'b', 'c', 'd', 'e'])
+Just (['a', 'b', 'c'])
-> S.dropLast(4, 'abcdefg')
-Just('abc')
+> S.dropLast (5) (['a', 'b', 'c', 'd', 'e'])
+Just ([])
-> S.dropLast(4, 'abc')
+> S.dropLast (6) (['a', 'b', 'c', 'd', 'e'])
Nothing
```
-### Array
-
-
+#### `size :: Foldable f => f a -> Integer`
Returns the number of elements of the given structure.
```javascript
-> S.size([])
+> S.size ([])
0
-> S.size(['foo', 'bar', 'baz'])
+> S.size (['foo', 'bar', 'baz'])
3
-> S.size(Nil)
+> S.size (Nil)
0
-> S.size(Cons('foo', Cons('bar', Cons('baz', Nil))))
+> S.size (Cons ('foo') (Cons ('bar') (Cons ('baz') (Nil))))
3
-> S.size(S.Nothing)
+> S.size (S.Nothing)
0
-> S.size(S.Just('quux'))
+> S.size (S.Just ('quux'))
+1
+
+> S.size (S.Pair ('ignored!') ('counted!'))
1
```
-
+#### `append :: (Applicative f, Semigroup (f a)) => a -> f a -> f a`
Returns the result of appending the first argument to the second.
See also [`prepend`](#prepend).
```javascript
-> S.append(3, [1, 2])
+> S.append (3) ([1, 2])
[1, 2, 3]
-> S.append(3, Cons(1, Cons(2, Nil)))
-Cons(1, Cons(2, Cons(3, Nil)))
+> S.append (3) (Cons (1) (Cons (2) (Nil)))
+Cons (1) (Cons (2) (Cons (3) (Nil)))
-> S.append([1], S.Nothing)
-Just([1])
+> S.append ([1]) (S.Nothing)
+Just ([1])
-> S.append([3], S.Just([1, 2]))
-Just([1, 2, 3])
+> S.append ([3]) (S.Just ([1, 2]))
+Just ([1, 2, 3])
```
-
+#### `prepend :: (Applicative f, Semigroup (f a)) => a -> f a -> f a`
Returns the result of prepending the first argument to the second.
See also [`append`](#append).
```javascript
-> S.prepend(1, [2, 3])
+> S.prepend (1) ([2, 3])
[1, 2, 3]
-> S.prepend(1, Cons(2, Cons(3, Nil)))
-Cons(1, Cons(2, Cons(3, Nil)))
+> S.prepend (1) (Cons (2) (Cons (3) (Nil)))
+Cons (1) (Cons (2) (Cons (3) (Nil)))
-> S.prepend([1], S.Nothing)
-Just([1])
+> S.prepend ([1]) (S.Nothing)
+Just ([1])
-> S.prepend([1], S.Just([2, 3]))
-Just([1, 2, 3])
+> S.prepend ([1]) (S.Just ([2, 3]))
+Just ([1, 2, 3])
```
-
+#### `joinWith :: String -> Array String -> String`
Joins the strings of the second argument separated by the first argument.
Properties:
- - `forall s :: String, t :: String. S.joinWith(s, S.splitOn(s, t)) = t`
+ - `forall s :: String, t :: String.
+ S.joinWith (s) (S.splitOn (s) (t)) = t`
See also [`splitOn`](#splitOn).
```javascript
-> S.joinWith(':', ['foo', 'bar', 'baz'])
+> S.joinWith (':') (['foo', 'bar', 'baz'])
'foo:bar:baz'
```
-
+#### `elem :: (Setoid a, Foldable f) => a -> f a -> Boolean`
Takes a value and a structure and returns `true` [iff][] the value is an
element of the structure.
@@ -2588,29 +2160,29 @@ element of the structure.
See also [`find`](#find).
```javascript
-> S.elem('c', ['a', 'b', 'c'])
+> S.elem ('c') (['a', 'b', 'c'])
true
-> S.elem('x', ['a', 'b', 'c'])
+> S.elem ('x') (['a', 'b', 'c'])
false
-> S.elem(3, {x: 1, y: 2, z: 3})
+> S.elem (3) ({x: 1, y: 2, z: 3})
true
-> S.elem(8, {x: 1, y: 2, z: 3})
+> S.elem (8) ({x: 1, y: 2, z: 3})
false
-> S.elem(0, S.Just(0))
+> S.elem (0) (S.Just (0))
true
-> S.elem(0, S.Just(1))
+> S.elem (0) (S.Just (1))
false
-> S.elem(0, S.Nothing)
+> S.elem (0) (S.Nothing)
false
```
-
+#### `find :: Foldable f => (a -> Boolean) -> f a -> Maybe a`
Takes a predicate and a structure and returns Just the leftmost element
of the structure which satisfies the predicate; Nothing if there is no
@@ -2619,27 +2191,24 @@ such element.
See also [`elem`](#elem).
```javascript
-> S.find(n => n < 0, [1, -2, 3, -4, 5])
-Just(-2)
+> S.find (S.lt (0)) ([1, -2, 3, -4, 5])
+Just (-2)
-> S.find(n => n < 0, [1, 2, 3, 4, 5])
+> S.find (S.lt (0)) ([1, 2, 3, 4, 5])
Nothing
```
-
+#### `foldMap :: (Monoid m, Foldable f) => TypeRep m -> (a -> m) -> f a -> m`
-Combines [`map`](#map) and [`prop`](#prop). `pluck(k, xs)` is equivalent
-to `map(prop(k), xs)`.
+Curried version of [`Z.foldMap`][]. Deconstructs a foldable by mapping
+every element to a monoid and concatenating the results.
```javascript
-> S.pluck('x', [{x: 1}, {x: 2}, {x: 3}])
-[1, 2, 3]
-
-> S.pluck('x', S.Just({x: 1, y: 2, z: 3}))
-Just(1)
+> S.foldMap (String) (f => f.name) ([Math.sin, Math.cos, Math.tan])
+'sincostan'
```
-
+#### `unfoldr :: (b -> Maybe (Pair a b)) -> b -> Array a`
Takes a function and a seed value, and returns an array generated by
applying the function repeatedly. The array is initially empty. The
@@ -2652,28 +2221,28 @@ of the function should result in either:
the array and the function is applied to the second element.
```javascript
-> S.unfoldr(n => n < 5 ? S.Just([n, n + 1]) : S.Nothing, 1)
+> S.unfoldr (n => n < 5 ? S.Just (S.Pair (n) (n + 1)) : S.Nothing) (1)
[1, 2, 3, 4]
```
-
+#### `range :: Integer -> Integer -> Array Integer`
Returns an array of consecutive integers starting with the first argument
and ending with the second argument minus one. Returns `[]` if the second
argument is less than or equal to the first argument.
```javascript
-> S.range(0, 10)
+> S.range (0) (10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-> S.range(-5, 0)
+> S.range (-5) (0)
[-5, -4, -3, -2, -1]
-> S.range(0, -5)
+> S.range (0) (-5)
[]
```
-
+#### `groupBy :: (a -> a -> Boolean) -> Array a -> Array (Array a)`
Splits its array argument into an array of arrays of equal,
adjacent elements. Equality is determined by the function
@@ -2684,51 +2253,51 @@ for functions that aren't reflexive, transitive, and symmetric
Properties:
- `forall f :: a -> a -> Boolean, xs :: Array a.
- S.join(S.groupBy(f, xs)) = xs`
+ S.join (S.groupBy (f) (xs)) = xs`
```javascript
-> S.groupBy(S.equals, [1, 1, 2, 1, 1])
+> S.groupBy (S.equals) ([1, 1, 2, 1, 1])
[[1, 1], [2], [1, 1]]
-> S.groupBy(x => y => x + y === 0, [2, -3, 3, 3, 3, 4, -4, 4])
+> S.groupBy (x => y => x + y === 0) ([2, -3, 3, 3, 3, 4, -4, 4])
[[2], [-3, 3, 3, 3], [4, -4], [4]]
```
-
+#### `reverse :: (Applicative f, Foldable f, Monoid (f a)) => f a -> f a`
Reverses the elements of the given structure.
```javascript
-> S.reverse([1, 2, 3])
+> S.reverse ([1, 2, 3])
[3, 2, 1]
-> S.reverse(Cons(1, Cons(2, Cons(3, Nil))))
-Cons(3, Cons(2, Cons(1, Nil)))
+> S.reverse (Cons (1) (Cons (2) (Cons (3) (Nil))))
+Cons (3) (Cons (2) (Cons (1) (Nil)))
-> S.pipe([S.splitOn(''), S.reverse, S.joinWith('')], 'abc')
+> S.pipe ([S.splitOn (''), S.reverse, S.joinWith ('')]) ('abc')
'cba'
```
-
+#### `sort :: (Ord a, Applicative m, Foldable m, Monoid (m a)) => m a -> m a`
Performs a [stable sort][] of the elements of the given structure, using
[`Z.lte`][] for comparisons.
Properties:
- - `S.sort(S.sort(m)) = S.sort(m)` (idempotence)
+ - `S.sort (S.sort (m)) = S.sort (m)` (idempotence)
See also [`sortBy`](#sortBy).
```javascript
-> S.sort(['foo', 'bar', 'baz'])
+> S.sort (['foo', 'bar', 'baz'])
['bar', 'baz', 'foo']
-> S.sort([S.Left(4), S.Right(3), S.Left(2), S.Right(1)])
-[Left(2), Left(4), Right(1), Right(3)]
+> S.sort ([S.Left (4), S.Right (3), S.Left (2), S.Right (1)])
+[Left (2), Left (4), Right (1), Right (3)]
```
-
+#### `sortBy :: (Ord b, Applicative m, Foldable m, Monoid (m a)) => (a -> b) -> m a -> m a`
Performs a [stable sort][] of the elements of the given structure, using
[`Z.lte`][] to compare the values produced by applying the given function
@@ -2736,12 +2305,12 @@ to each element of the structure.
Properties:
- - `S.sortBy(f, S.sortBy(f, m)) = S.sortBy(f, m)` (idempotence)
+ - `S.sortBy (f) (S.sortBy (f) (m)) = S.sortBy (f) (m)` (idempotence)
See also [`sort`](#sort).
```javascript
-> S.sortBy(S.prop('rank'), [
+> S.sortBy (S.prop ('rank')) ([
. {rank: 7, suit: 'spades'},
. {rank: 5, suit: 'hearts'},
. {rank: 2, suit: 'hearts'},
@@ -2752,7 +2321,7 @@ See also [`sort`](#sort).
. {rank: 5, suit: 'spades'},
. {rank: 7, suit: 'spades'} ]
-> S.sortBy(S.prop('suit'), [
+> S.sortBy (S.prop ('suit')) ([
. {rank: 7, suit: 'spades'},
. {rank: 5, suit: 'hearts'},
. {rank: 2, suit: 'hearts'},
@@ -2764,9 +2333,48 @@ See also [`sort`](#sort).
. {rank: 5, suit: 'spades'} ]
```
+If descending order is desired, one may use [`Descending`][]:
+
+```javascript
+> S.sortBy (Descending) ([83, 97, 110, 99, 116, 117, 97, 114, 121])
+[121, 117, 116, 114, 110, 99, 97, 97, 83]
+```
+
+#### `zip :: Array a -> Array b -> Array (Pair a b)`
+
+Returns an array of pairs of corresponding elements from the given
+arrays. The length of the resulting array is equal to the length of
+the shorter input array.
+
+See also [`zipWith`](#zipWith).
+
+```javascript
+> S.zip (['a', 'b']) (['x', 'y', 'z'])
+[Pair ('a') ('x'), Pair ('b') ('y')]
+
+> S.zip ([1, 3, 5]) ([2, 4])
+[Pair (1) (2), Pair (3) (4)]
+```
+
+#### `zipWith :: (a -> b -> c) -> Array a -> Array b -> Array c`
+
+Returns the result of combining, pairwise, the given arrays using the
+given binary function. The length of the resulting array is equal to the
+length of the shorter input array.
+
+See also [`zip`](#zip).
+
+```javascript
+> S.zipWith (a => b => a + b) (['a', 'b']) (['x', 'y', 'z'])
+['ax', 'by']
+
+> S.zipWith (a => b => [a, b]) ([1, 3, 5]) ([2, 4])
+[[1, 2], [3, 4]]
+```
+
### Object
-
+#### `prop :: String -> a -> b`
Takes a property name and an object with known properties and returns
the value of the specified property. If for some reason the object
@@ -2774,14 +2382,12 @@ lacks the specified property, a type error is thrown.
For accessing properties of uncertain objects, use [`get`](#get) instead.
-See also [`pluck`](#pluck).
-
```javascript
-> S.prop('a', {a: 1, b: 2})
+> S.prop ('a') ({a: 1, b: 2})
1
```
-
+#### `props :: Array String -> a -> b`
Takes a property path (an array of property names) and an object with
known structure and returns the value at the given path. If for some
@@ -2791,11 +2397,11 @@ For accessing property paths of uncertain objects, use [`gets`](#gets)
instead.
```javascript
-> S.props(['a', 'b', 'c'], {a: {b: {c: 1}}})
+> S.props (['a', 'b', 'c']) ({a: {b: {c: 1}}})
1
```
-
+#### `get :: (Any -> Boolean) -> String -> a -> Maybe b`
Takes a predicate, a property name, and an object and returns Just the
value of the specified object property if it exists and the value
@@ -2804,23 +2410,23 @@ satisfies the given predicate; Nothing otherwise.
See also [`gets`](#gets) and [`prop`](#prop).
```javascript
-> S.get(S.is(Number), 'x', {x: 1, y: 2})
-Just(1)
+> S.get (S.is ($.Number)) ('x') ({x: 1, y: 2})
+Just (1)
-> S.get(S.is(Number), 'x', {x: '1', y: '2'})
+> S.get (S.is ($.Number)) ('x') ({x: '1', y: '2'})
Nothing
-> S.get(S.is(Number), 'x', {})
+> S.get (S.is ($.Number)) ('x') ({})
Nothing
-> S.get($.test([], $.Array($.Number)), 'x', {x: [1, 2, 3]})
-Just([1, 2, 3])
+> S.get (S.is ($.Array ($.Number))) ('x') ({x: [1, 2, 3]})
+Just ([1, 2, 3])
-> S.get($.test([], $.Array($.Number)), 'x', {x: [1, 2, 3, null]})
+> S.get (S.is ($.Array ($.Number))) ('x') ({x: [1, 2, 3, null]})
Nothing
```
-
+#### `gets :: (Any -> Boolean) -> Array String -> a -> Maybe b`
Takes a predicate, a property path (an array of property names), and
an object and returns Just the value at the given path if such a path
@@ -2829,13 +2435,13 @@ exists and the value satisfies the given predicate; Nothing otherwise.
See also [`get`](#get).
```javascript
-> S.gets(S.is(Number), ['a', 'b', 'c'], {a: {b: {c: 42}}})
-Just(42)
+> S.gets (S.is ($.Number)) (['a', 'b', 'c']) ({a: {b: {c: 42}}})
+Just (42)
-> S.gets(S.is(Number), ['a', 'b', 'c'], {a: {b: {c: '42'}}})
+> S.gets (S.is ($.Number)) (['a', 'b', 'c']) ({a: {b: {c: '42'}}})
Nothing
-> S.gets(S.is(Number), ['a', 'b', 'c'], {})
+> S.gets (S.is ($.Number)) (['a', 'b', 'c']) ({})
Nothing
```
@@ -2847,17 +2453,17 @@ the same type. Formally, a value is a member of type `StrMap a` if its
[type identifier][] is `'Object'` and the values of its enumerable own
properties are all members of type `a`.
-
+#### `singleton :: String -> a -> StrMap a`
Takes a string and a value of any type, and returns a string map with
a single entry (mapping the key to the value).
```javascript
-> S.singleton('foo', 42)
+> S.singleton ('foo') (42)
{foo: 42}
```
-
+#### `insert :: String -> a -> StrMap a -> StrMap a`
Takes a string, a value of any type, and a string map, and returns a
string map comprising all the entries of the given string map plus the
@@ -2867,14 +2473,14 @@ Equivalent to Haskell's `insert` function. Similar to Clojure's `assoc`
function.
```javascript
-> S.insert('c', 3, {a: 1, b: 2})
+> S.insert ('c') (3) ({a: 1, b: 2})
{a: 1, b: 2, c: 3}
-> S.insert('a', 4, {a: 1, b: 2})
+> S.insert ('a') (4) ({a: 1, b: 2})
{a: 4, b: 2}
```
-
+#### `remove :: String -> StrMap a -> StrMap a`
Takes a string and a string map, and returns a string map comprising all
the entries of the given string map except the one whose key matches the
@@ -2884,269 +2490,226 @@ Equivalent to Haskell's `delete` function. Similar to Clojure's `dissoc`
function.
```javascript
-> S.remove('c', {a: 1, b: 2, c: 3})
+> S.remove ('c') ({a: 1, b: 2, c: 3})
{a: 1, b: 2}
-> S.remove('c', {})
+> S.remove ('c') ({})
{}
```
-
+#### `keys :: StrMap a -> Array String`
Returns the keys of the given string map, in arbitrary order.
```javascript
-> S.keys({b: 2, c: 3, a: 1}).sort()
+> S.sort (S.keys ({b: 2, c: 3, a: 1}))
['a', 'b', 'c']
```
-
+#### `values :: StrMap a -> Array a`
Returns the values of the given string map, in arbitrary order.
```javascript
-> S.values({a: 1, c: 3, b: 2}).sort()
+> S.sort (S.values ({a: 1, c: 3, b: 2}))
[1, 2, 3]
```
-
+#### `pairs :: StrMap a -> Array (Pair String a)`
Returns the key–value pairs of the given string map, in arbitrary order.
```javascript
-> S.pairs({b: 2, a: 1, c: 3}).sort()
-[['a', 1], ['b', 2], ['c', 3]]
+> S.sort (S.pairs ({b: 2, a: 1, c: 3}))
+[Pair ('a') (1), Pair ('b') (2), Pair ('c') (3)]
```
-
+#### `fromPairs :: Foldable f => f (Pair String a) -> StrMap a`
Returns a string map containing the key–value pairs specified by the
given [Foldable][]. If a key appears in multiple pairs, the rightmost
pair takes precedence.
```javascript
-> S.fromPairs([['a', 1], ['b', 2], ['c', 3]])
+> S.fromPairs ([S.Pair ('a') (1), S.Pair ('b') (2), S.Pair ('c') (3)])
{a: 1, b: 2, c: 3}
-> S.fromPairs([['x', 1], ['x', 2]])
+> S.fromPairs ([S.Pair ('x') (1), S.Pair ('x') (2)])
{x: 2}
```
### Number
-
+#### `negate :: ValidNumber -> ValidNumber`
Negates its argument.
```javascript
-> S.negate(12.5)
+> S.negate (12.5)
-12.5
-> S.negate(-42)
+> S.negate (-42)
42
```
-
+#### `add :: FiniteNumber -> FiniteNumber -> FiniteNumber`
Returns the sum of two (finite) numbers.
```javascript
-> S.add(1, 1)
+> S.add (1) (1)
2
```
-
+#### `sum :: Foldable f => f FiniteNumber -> FiniteNumber`
Returns the sum of the given array of (finite) numbers.
```javascript
-> S.sum([1, 2, 3, 4, 5])
+> S.sum ([1, 2, 3, 4, 5])
15
-> S.sum([])
+> S.sum ([])
0
-> S.sum(S.Just(42))
+> S.sum (S.Just (42))
42
-> S.sum(S.Nothing)
+> S.sum (S.Nothing)
0
```
-
+#### `sub :: FiniteNumber -> FiniteNumber -> FiniteNumber`
Takes a finite number `n` and returns the _subtract `n`_ function.
-See also [`sub_`](#sub_).
-
```javascript
-> S.map(S.sub(1), [1, 2, 3])
+> S.map (S.sub (1)) ([1, 2, 3])
[0, 1, 2]
```
-
-
-Returns the difference between two (finite) numbers.
-
-See also [`sub`](#sub).
-
-```javascript
-> S.sub_(4, 2)
-2
-```
-
-
+#### `mult :: FiniteNumber -> FiniteNumber -> FiniteNumber`
Returns the product of two (finite) numbers.
```javascript
-> S.mult(4, 2)
+> S.mult (4) (2)
8
```
-
+#### `product :: Foldable f => f FiniteNumber -> FiniteNumber`
Returns the product of the given array of (finite) numbers.
```javascript
-> S.product([1, 2, 3, 4, 5])
+> S.product ([1, 2, 3, 4, 5])
120
-> S.product([])
+> S.product ([])
1
-> S.product(S.Just(42))
+> S.product (S.Just (42))
42
-> S.product(S.Nothing)
+> S.product (S.Nothing)
1
```
-
+#### `div :: NonZeroFiniteNumber -> FiniteNumber -> FiniteNumber`
Takes a non-zero finite number `n` and returns the _divide by `n`_
function.
-See also [`div_`](#div_).
-
```javascript
-> S.map(S.div(2), [0, 1, 2, 3])
+> S.map (S.div (2)) ([0, 1, 2, 3])
[0, 0.5, 1, 1.5]
```
-
-
-Returns the result of dividing its first argument (a finite number) by
-its second argument (a non-zero finite number).
-
-See also [`div`](#div).
-
-```javascript
-> S.div_(7, 2)
-3.5
-
-> S.map(S.div_(24), [1, 2, 3, 4])
-[24, 12, 8, 6]
-```
-
-
+#### `pow :: FiniteNumber -> FiniteNumber -> FiniteNumber`
Takes a finite number `n` and returns the _power of `n`_ function.
-See also [`pow_`](#pow_).
-
```javascript
-> S.map(S.pow(2), [-3, -2, -1, 0, 1, 2, 3])
+> S.map (S.pow (2)) ([-3, -2, -1, 0, 1, 2, 3])
[9, 4, 1, 0, 1, 4, 9]
-> S.map(S.pow(0.5), [1, 4, 9, 16, 25])
+> S.map (S.pow (0.5)) ([1, 4, 9, 16, 25])
[1, 2, 3, 4, 5]
```
-
-
-Curried version of [`Math.pow`][].
-
-See also [`pow`](#pow).
-
-```javascript
-> S.map(S.pow_(10), [-3, -2, -1, 0, 1, 2, 3])
-[0.001, 0.01, 0.1, 1, 10, 100, 1000]
-```
-
-
+#### `mean :: Foldable f => f FiniteNumber -> Maybe FiniteNumber`
Returns the mean of the given array of (finite) numbers.
```javascript
-> S.mean([1, 2, 3, 4, 5])
-Just(3)
+> S.mean ([1, 2, 3, 4, 5])
+Just (3)
-> S.mean([])
+> S.mean ([])
Nothing
-> S.mean(S.Just(42))
-Just(42)
+> S.mean (S.Just (42))
+Just (42)
-> S.mean(S.Nothing)
+> S.mean (S.Nothing)
Nothing
```
### Integer
-
+#### `even :: Integer -> Boolean`
Returns `true` if the given integer is even; `false` if it is odd.
```javascript
-> S.even(42)
+> S.even (42)
true
-> S.even(99)
+> S.even (99)
false
```
-
+#### `odd :: Integer -> Boolean`
Returns `true` if the given integer is odd; `false` if it is even.
```javascript
-> S.odd(99)
+> S.odd (99)
true
-> S.odd(42)
+> S.odd (42)
false
```
### Parse
-
+#### `parseDate :: String -> Maybe ValidDate`
Takes a string and returns Just the date represented by the string
if it does in fact represent a date; Nothing otherwise.
```javascript
-> S.parseDate('2011-01-19T17:40:00Z')
-Just(new Date('2011-01-19T17:40:00.000Z'))
+> S.parseDate ('2011-01-19T17:40:00Z')
+Just (new Date ('2011-01-19T17:40:00.000Z'))
-> S.parseDate('today')
+> S.parseDate ('today')
Nothing
```
-
+#### `parseFloat :: String -> Maybe Number`
Takes a string and returns Just the number represented by the string
if it does in fact represent a number; Nothing otherwise.
```javascript
-> S.parseFloat('-123.45')
-Just(-123.45)
+> S.parseFloat ('-123.45')
+Just (-123.45)
-> S.parseFloat('foo.bar')
+> S.parseFloat ('foo.bar')
Nothing
```
-
+#### `parseInt :: Radix -> String -> Maybe Integer`
Takes a radix (an integer between 2 and 36 inclusive) and a string,
and returns Just the number represented by the string if it does in
@@ -3158,75 +2721,76 @@ is considered to represent an integer only if all its non-prefix
characters are members of the character set specified by the radix.
```javascript
-> S.parseInt(10, '-42')
-Just(-42)
+> S.parseInt (10) ('-42')
+Just (-42)
-> S.parseInt(16, '0xFF')
-Just(255)
+> S.parseInt (16) ('0xFF')
+Just (255)
-> S.parseInt(16, '0xGG')
+> S.parseInt (16) ('0xGG')
Nothing
```
-
+#### `parseJson :: (Any -> Boolean) -> String -> Maybe a`
Takes a predicate and a string which may or may not be valid JSON, and
returns Just the result of applying `JSON.parse` to the string *if* the
result satisfies the predicate; Nothing otherwise.
```javascript
-> S.parseJson($.test([], $.Array($.Integer)), '[')
+> S.parseJson (S.is ($.Array ($.Integer))) ('[')
Nothing
-> S.parseJson($.test([], $.Array($.Integer)), '["1","2","3"]')
+> S.parseJson (S.is ($.Array ($.Integer))) ('["1","2","3"]')
Nothing
-> S.parseJson($.test([], $.Array($.Integer)), '[0,1.5,3,4.5]')
+> S.parseJson (S.is ($.Array ($.Integer))) ('[0,1.5,3,4.5]')
Nothing
-> S.parseJson($.test([], $.Array($.Integer)), '[1,2,3]')
-Just([1, 2, 3])
+> S.parseJson (S.is ($.Array ($.Integer))) ('[1,2,3]')
+Just ([1, 2, 3])
```
### RegExp
-
+#### `regex :: RegexFlags -> String -> RegExp`
Takes a [RegexFlags][] and a pattern, and returns a RegExp.
```javascript
-> S.regex('g', ':\\d+:')
+> S.regex ('g') (':\\d+:')
/:\d+:/g
```
-
+#### `regexEscape :: String -> String`
Takes a string which may contain regular expression metacharacters,
and returns a string with those metacharacters escaped.
Properties:
- - `forall s :: String. S.test(S.regex('', S.regexEscape(s)), s) = true`
+ - `forall s :: String.
+ S.test (S.regex ('') (S.regexEscape (s))) (s) = true`
```javascript
-> S.regexEscape('-=*{XYZ}*=-')
+> S.regexEscape ('-=*{XYZ}*=-')
'\\-=\\*\\{XYZ\\}\\*=\\-'
```
-
+#### `test :: RegExp -> String -> Boolean`
Takes a pattern and a string, and returns `true` [iff][] the pattern
matches the string.
```javascript
-> S.test(/^a/, 'abacus')
+> S.test (/^a/) ('abacus')
true
-> S.test(/^a/, 'banana')
+> S.test (/^a/) ('banana')
false
```
-
+#### `match :: NonGlobalRegExp -> String -> Maybe { match :: String, groups :: Array (Maybe String) }`
Takes a pattern and a string, and returns Just a match record if the
pattern matches the string; Nothing otherwise.
@@ -3237,19 +2801,20 @@ capturing groups.
Properties:
- `forall p :: Pattern, s :: String.
- S.head(S.matchAll(S.regex('g', p), s)) = S.match(S.regex('', p), s)`
+ S.head (S.matchAll (S.regex ('g') (p)) (s))
+ = S.match (S.regex ('') (p)) (s)`
See also [`matchAll`](#matchAll).
```javascript
-> S.match(/(good)?bye/, 'goodbye')
-Just({match: 'goodbye', groups: [Just('good')]})
+> S.match (/(good)?bye/) ('goodbye')
+Just ({match: 'goodbye', groups: [Just ('good')]})
-> S.match(/(good)?bye/, 'bye')
-Just({match: 'bye', groups: [Nothing]})
+> S.match (/(good)?bye/) ('bye')
+Just ({match: 'bye', groups: [Nothing]})
```
-
+#### `matchAll :: GlobalRegExp -> String -> Array { match :: String, groups :: Array (Maybe String) }`
Takes a pattern and a string, and returns an array of match records.
@@ -3259,49 +2824,49 @@ capturing groups.
See also [`match`](#match).
```javascript
-> S.matchAll(/@([a-z]+)/g, 'Hello, world!')
+> S.matchAll (/@([a-z]+)/g) ('Hello, world!')
[]
-> S.matchAll(/@([a-z]+)/g, 'Hello, @foo! Hello, @bar! Hello, @baz!')
-[ {match: '@foo', groups: [Just('foo')]},
-. {match: '@bar', groups: [Just('bar')]},
-. {match: '@baz', groups: [Just('baz')]} ]
+> S.matchAll (/@([a-z]+)/g) ('Hello, @foo! Hello, @bar! Hello, @baz!')
+[ {match: '@foo', groups: [Just ('foo')]},
+. {match: '@bar', groups: [Just ('bar')]},
+. {match: '@baz', groups: [Just ('baz')]} ]
```
### String
-
+#### `toUpper :: String -> String`
Returns the upper-case equivalent of its argument.
See also [`toLower`](#toLower).
```javascript
-> S.toUpper('ABC def 123')
+> S.toUpper ('ABC def 123')
'ABC DEF 123'
```
-
+#### `toLower :: String -> String`
Returns the lower-case equivalent of its argument.
See also [`toUpper`](#toUpper).
```javascript
-> S.toLower('ABC def 123')
+> S.toLower ('ABC def 123')
'abc def 123'
```
-
+#### `trim :: String -> String`
Strips leading and trailing whitespace characters.
```javascript
-> S.trim('\t\t foo bar \n')
+> S.trim ('\t\t foo bar \n')
'foo bar'
```
-
+#### `stripPrefix :: String -> String -> Maybe String`
Returns Just the portion of the given string (the second argument) left
after removing the given prefix (the first argument) if the string starts
@@ -3310,14 +2875,14 @@ with the prefix; Nothing otherwise.
See also [`stripSuffix`](#stripSuffix).
```javascript
-> S.stripPrefix('https://', 'https://sanctuary.js.org')
-Just('sanctuary.js.org')
+> S.stripPrefix ('https://') ('https://sanctuary.js.org')
+Just ('sanctuary.js.org')
-> S.stripPrefix('https://', 'http://sanctuary.js.org')
+> S.stripPrefix ('https://') ('http://sanctuary.js.org')
Nothing
```
-
+#### `stripSuffix :: String -> String -> Maybe String`
Returns Just the portion of the given string (the second argument) left
after removing the given suffix (the first argument) if the string ends
@@ -3326,14 +2891,14 @@ with the suffix; Nothing otherwise.
See also [`stripPrefix`](#stripPrefix).
```javascript
-> S.stripSuffix('.md', 'README.md')
-Just('README')
+> S.stripSuffix ('.md') ('README.md')
+Just ('README')
-> S.stripSuffix('.md', 'README')
+> S.stripSuffix ('.md') ('README')
Nothing
```
-
+#### `words :: String -> Array String`
Takes a string and returns the array of words the string contains
(words are delimited by whitespace characters).
@@ -3341,11 +2906,11 @@ Takes a string and returns the array of words the string contains
See also [`unwords`](#unwords).
```javascript
-> S.words(' foo bar baz ')
+> S.words (' foo bar baz ')
['foo', 'bar', 'baz']
```
-
+#### `unwords :: Array String -> String`
Takes an array of words and returns the result of joining the words
with separating spaces.
@@ -3353,11 +2918,11 @@ with separating spaces.
See also [`words`](#words).
```javascript
-> S.unwords(['foo', 'bar', 'baz'])
+> S.unwords (['foo', 'bar', 'baz'])
'foo bar baz'
```
-
+#### `lines :: String -> Array String`
Takes a string and returns the array of lines the string contains
(lines are delimited by newlines: `'\n'` or `'\r\n'` or `'\r'`).
@@ -3366,11 +2931,11 @@ The resulting strings do not contain newlines.
See also [`unlines`](#unlines).
```javascript
-> S.lines('foo\nbar\nbaz\n')
+> S.lines ('foo\nbar\nbaz\n')
['foo', 'bar', 'baz']
```
-
+#### `unlines :: Array String -> String`
Takes an array of lines and returns the result of joining the lines
after appending a terminating line feed (`'\n'`) to each.
@@ -3378,11 +2943,11 @@ after appending a terminating line feed (`'\n'`) to each.
See also [`lines`](#lines).
```javascript
-> S.unlines(['foo', 'bar', 'baz'])
+> S.unlines (['foo', 'bar', 'baz'])
'foo\nbar\nbaz\n'
```
-
+#### `splitOn :: String -> String -> Array String`
Returns the substrings of its second argument separated by occurrences
of its first argument.
@@ -3390,11 +2955,11 @@ of its first argument.
See also [`joinWith`](#joinWith) and [`splitOnRegex`](#splitOnRegex).
```javascript
-> S.splitOn('::', 'foo::bar::baz')
+> S.splitOn ('::') ('foo::bar::baz')
['foo', 'bar', 'baz']
```
-
+#### `splitOnRegex :: GlobalRegExp -> String -> Array String`
Takes a pattern and a string, and returns the result of splitting the
string at every non-overlapping occurrence of the pattern.
@@ -3402,85 +2967,95 @@ string at every non-overlapping occurrence of the pattern.
Properties:
- `forall s :: String, t :: String.
- S.joinWith(s, S.splitOnRegex(S.regex('g', S.regexEscape(s)), t))
+ S.joinWith (s)
+ (S.splitOnRegex (S.regex ('g') (S.regexEscape (s))) (t))
= t`
See also [`splitOn`](#splitOn).
```javascript
-> S.splitOnRegex(/[,;][ ]*/g, 'foo, bar, baz')
+> S.splitOnRegex (/[,;][ ]*/g) ('foo, bar, baz')
['foo', 'bar', 'baz']
-> S.splitOnRegex(/[,;][ ]*/g, 'foo;bar;baz')
+> S.splitOnRegex (/[,;][ ]*/g) ('foo;bar;baz')
['foo', 'bar', 'baz']
```
-[$.Array]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.14.0#Array
-[$.String]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.14.0#String
-[Alt]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#alt
-[Alternative]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#alternative
-[Applicative]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#applicative
-[Apply]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#apply
-[Bifunctor]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#bifunctor
-[BinaryType]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.14.0#BinaryType
-[Either]: #either-type
-[Extend]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#extend
-[Fantasy Land]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0
-[Foldable]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#foldable
-[Haskell]: https://www.haskell.org/
-[Maybe]: #maybe-type
-[Monad]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#monad
-[Monoid]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#monoid
-[Nullable]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.14.0#Nullable
-[Ord]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#ord
-[PureScript]: http://www.purescript.org/
-[Ramda]: http://ramdajs.com/
-[RegexFlags]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.14.0#RegexFlags
-[Semigroup]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#semigroup
-[Semigroupoid]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#semigroupoid
-[Traversable]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#traversable
-[UnaryType]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.14.0#UnaryType
-[`Math.pow`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow
-[`Z.alt`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#alt
-[`Z.ap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#ap
-[`Z.apFirst`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#apFirst
-[`Z.apSecond`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#apSecond
-[`Z.bimap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#bimap
-[`Z.chain`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#chain
-[`Z.chainRec`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#chainRec
-[`Z.compose`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#compose
-[`Z.concat`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#concat
-[`Z.contramap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#contramap
-[`Z.empty`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#empty
-[`Z.equals`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#equals
-[`Z.extend`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#extend
-[`Z.extract`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#extract
-[`Z.filter`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#filter
-[`Z.filterM`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#filterM
-[`Z.gt`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#gt
-[`Z.gte`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#gte
-[`Z.id`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#id
-[`Z.invert`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#invert
-[`Z.join`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#join
-[`Z.lt`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#lt
-[`Z.lte`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#lte
-[`Z.map`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#map
-[`Z.of`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#of
-[`Z.promap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#promap
-[`Z.sequence`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#sequence
-[`Z.toString`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#toString
-[`Z.traverse`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#traverse
-[`Z.zero`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v7.1.1#zero
-[`of`]: https://github.com/fantasyland/fantasy-land/tree/v3.4.0#of-method
-[equivalence]: https://en.wikipedia.org/wiki/Equivalence_relation
-[iff]: https://en.wikipedia.org/wiki/If_and_only_if
-[parseInt]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
-[sanctuary-def]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.14.0
-[stable sort]: https://en.wikipedia.org/wiki/Sorting_algorithm#Stability
-[thrush]: https://github.com/raganwald-deprecated/homoiconic/blob/master/2008-10-30/thrush.markdown
-[type identifier]: https://github.com/sanctuary-js/sanctuary-type-identifiers/tree/v2.0.1
-
-[`Either#fantasy-land/bimap`]: #Either.prototype.fantasy-land/bimap
-[`Either#fantasy-land/map`]: #Either.prototype.fantasy-land/map
-[`Either#toString`]: #Either.prototype.toString
-[`Maybe#toString`]: #Maybe.prototype.toString
+[#438]: https://github.com/sanctuary-js/sanctuary/issues/438
+[Apply]: https://github.com/fantasyland/fantasy-land/tree/v3.5.0#apply
+[BinaryType]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.18.1#BinaryType
+[Chain]: https://github.com/fantasyland/fantasy-land/tree/v3.5.0#chain
+[Either]: #either-type
+[Fantasy Land]: https://github.com/fantasyland/fantasy-land/tree/v3.5.0
+[Foldable]: https://github.com/fantasyland/fantasy-land/tree/v3.5.0#foldable
+[GIGO]: https://en.wikipedia.org/wiki/Garbage_in,_garbage_out
+[Haskell]: https://www.haskell.org/
+[Kleisli]: https://en.wikipedia.org/wiki/Kleisli_category
+[Maybe]: #maybe-type
+[Nullable]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.18.1#Nullable
+[PureScript]: http://www.purescript.org/
+[Ramda]: http://ramdajs.com/
+[RegexFlags]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.18.1#RegexFlags
+[Semigroupoid]: https://github.com/fantasyland/fantasy-land/tree/v3.5.0#semigroupoid
+[UnaryType]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.18.1#UnaryType
+[`$.test`]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.18.1#test
+[`Descending`]: https://github.com/sanctuary-js/sanctuary-descending/tree/v1.0.0#Descending
+[`R.__`]: http://ramdajs.com/docs/#__
+[`R.bind`]: http://ramdajs.com/docs/#bind
+[`R.invoker`]: http://ramdajs.com/docs/#invoker
+[`Z.alt`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#alt
+[`Z.ap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#ap
+[`Z.apFirst`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#apFirst
+[`Z.apSecond`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#apSecond
+[`Z.bimap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#bimap
+[`Z.chain`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#chain
+[`Z.chainRec`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#chainRec
+[`Z.compose`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#compose
+[`Z.concat`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#concat
+[`Z.contramap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#contramap
+[`Z.dropWhile`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#dropWhile
+[`Z.duplicate`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#duplicate
+[`Z.empty`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#empty
+[`Z.equals`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#equals
+[`Z.extend`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#extend
+[`Z.extract`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#extract
+[`Z.filter`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#filter
+[`Z.flip`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#flip
+[`Z.foldMap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#foldMap
+[`Z.gt`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#gt
+[`Z.gte`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#gte
+[`Z.id`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#id
+[`Z.invert`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#invert
+[`Z.join`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#join
+[`Z.lt`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#lt
+[`Z.lte`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#lte
+[`Z.map`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#map
+[`Z.mapLeft`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#mapLeft
+[`Z.of`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#of
+[`Z.promap`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#promap
+[`Z.reject`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#reject
+[`Z.sequence`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#sequence
+[`Z.takeWhile`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#takeWhile
+[`Z.traverse`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#traverse
+[`Z.zero`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#zero
+[`show`]: https://github.com/sanctuary-js/sanctuary-show/tree/v1.0.0#show
+[equivalence]: https://en.wikipedia.org/wiki/Equivalence_relation
+[iff]: https://en.wikipedia.org/wiki/If_and_only_if
+[parseInt]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
+[partial functions]: https://en.wikipedia.org/wiki/Partial_function
+[ramda/ramda#683]: https://github.com/ramda/ramda/issues/683
+[ramda/ramda#1413]: https://github.com/ramda/ramda/issues/1413
+[ramda/ramda#1419]: https://github.com/ramda/ramda/pull/1419
+[sanctuary-def]: https://github.com/sanctuary-js/sanctuary-def/tree/v0.18.1
+[sanctuary-either]: https://github.com/sanctuary-js/sanctuary-either/tree/v1.0.0
+[sanctuary-maybe]: https://github.com/sanctuary-js/sanctuary-maybe/tree/v1.0.0
+[sanctuary-pair]: https://github.com/sanctuary-js/sanctuary-pair/tree/v1.0.0
+[sanctuary-show]: https://github.com/sanctuary-js/sanctuary-show/tree/v1.0.0
+[sanctuary-type-classes]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0
+[stable sort]: https://en.wikipedia.org/wiki/Sorting_algorithm#Stability
+[thrush]: https://github.com/raganwald-deprecated/homoiconic/blob/master/2008-10-30/thrush.markdown
+[total functions]: https://en.wikipedia.org/wiki/Partial_function#Total_function
+[type checking]: #type-checking
+[type identifier]: https://github.com/sanctuary-js/sanctuary-type-identifiers/tree/v2.0.1
+[type representative]: https://github.com/fantasyland/fantasy-land/tree/v3.5.0#type-representatives
+[variadic functions]: https://en.wikipedia.org/wiki/Variadic_function
diff --git a/package.json b/package.json
index 6a025597..d9b12327 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "sanctuary",
- "version": "0.14.1",
+ "version": "0.15.0",
"description": "Refuge from unsafe JavaScript",
"license": "MIT",
"repository": {