From 67de35f6054195db0f67a0f4c9aa9b04f88275a6 Mon Sep 17 00:00:00 2001 From: David Chambers Date: Thu, 25 Apr 2019 19:22:21 +0200 Subject: [PATCH] Version 0.20.0 --- README.md | 468 ++++++++++++++++++++++++++++++--------------------- index.js | 2 +- package.json | 2 +- 3 files changed, 282 insertions(+), 190 deletions(-) diff --git a/README.md b/README.md index e6f3151..8c0fbcc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # sanctuary-def sanctuary-def is a run-time type system for JavaScript. It facilitates -the definition of curried JavaScript functions which are explicit about +the definition of curried JavaScript functions that are explicit about the number of arguments to which they may be applied and the types of those arguments. @@ -13,7 +13,7 @@ const $ = require ('sanctuary-def'); The next step is to define an environment. An environment is an array of [types][]. [`env`][] is an environment containing all the built-in -JavaScript types. It may be used as the basis for environments which +JavaScript types. It may be used as the basis for environments that include custom types in addition to the built-in types: ```javascript @@ -170,57 +170,87 @@ add ('X'); ### Types Conceptually, a type is a set of values. One can think of a value of -type `Type` as a function of type `Any -> Boolean` which tests values +type `Type` as a function of type `Any -> Boolean` that tests values for membership in the set (though this is an oversimplification). -#### `Any :: Type` +#### `Unknown :: Type` + +Type used to represent missing type information. The type of `[]`, +for example, is `Array ???`. + +May be used with type constructors when defining environments. Given a +type constructor `List :: Type -> Type`, one could use `List ($.Unknown)` +to include an infinite number of types in an environment: + + - `List Number` + - `List String` + - `List (List Number)` + - `List (List String)` + - `List (List (List Number))` + - `List (List (List String))` + - `...` + +#### `Any :: Type` Type comprising every JavaScript value. -#### `AnyFunction :: Type` +#### `AnyFunction :: Type` Type comprising every Function value. -#### `Arguments :: Type` +#### `Arguments :: Type` Type comprising every [`arguments`][arguments] object. -#### `Array :: Type -⁠> Type` +#### `Array :: Type -⁠> Type` Constructor for homogeneous Array types. -#### `Array0 :: Type` +#### `Array0 :: Type` Type whose sole member is `[]`. -#### `Array1 :: Type -⁠> Type` +#### `Array1 :: Type -⁠> Type` Constructor for singleton Array types. -#### `Array2 :: Type -⁠> Type -⁠> Type` +#### `Array2 :: Type -⁠> Type -⁠> Type` Constructor for heterogeneous Array types of length 2. `['foo', true]` is a member of `Array2 String Boolean`. -#### `Boolean :: Type` +#### `Boolean :: Type` Type comprising `true` and `false`. -#### `Date :: Type` +#### `Date :: Type` Type comprising every Date value. -#### `Error :: Type` +#### `ValidDate :: Type` + +Type comprising every [`Date`][] value except `new Date (NaN)`. + +#### `Descending :: Type -⁠> Type` + +[Descending][] type constructor. + +#### `Either :: Type -⁠> Type -⁠> Type` + +[Either][] type constructor. + +#### `Error :: Type` Type comprising every Error value, including values of more specific constructors such as [`SyntaxError`][] and [`TypeError`][]. -#### `FiniteNumber :: Type` +#### `Fn :: Type -⁠> Type -⁠> Type` -Type comprising every [`ValidNumber`][] value except `Infinity` and -`-Infinity`. +Binary type constructor for unary function types. `$.Fn (I) (O)` +represents `I -> O`, the type of functions that take a value of +type `I` and return a value of type `O`. -#### `Function :: NonEmpty (Array Type) -⁠> Type` +#### `Function :: NonEmpty (Array Type) -⁠> Type` Constructor for Function types. @@ -230,76 +260,93 @@ Examples: type; and - `$.Function ([a, b, a])` represents the `(a, b) -> a` type. -#### `GlobalRegExp :: Type` +#### `HtmlElement :: Type` -Type comprising every [`RegExp`][] value whose `global` flag is `true`. +Type comprising every [HTML element][]. -See also [`NonGlobalRegExp`][]. +#### `Identity :: Type -⁠> Type` -#### `HtmlElement :: Type` +[Identity][] type constructor. -Type comprising every [HTML element][]. +#### `Maybe :: Type -⁠> Type` -#### `Integer :: Type` +[Maybe][] type constructor. -Type comprising every integer in the range -[[`Number.MIN_SAFE_INTEGER`][min] .. [`Number.MAX_SAFE_INTEGER`][max]]. +#### `NonEmpty :: Type -⁠> Type` -#### `NegativeFiniteNumber :: Type` +Constructor for non-empty types. `$.NonEmpty ($.String)`, for example, is +the type comprising every [`String`][] value except `''`. -Type comprising every [`FiniteNumber`][] value less than zero. +The given type must satisfy the [Monoid][] and [Setoid][] specifications. -#### `NegativeInteger :: Type` +#### `Null :: Type` -Type comprising every [`Integer`][] value less than zero. +Type whose sole member is `null`. -#### `NegativeNumber :: Type` +#### `Nullable :: Type -⁠> Type` -Type comprising every [`Number`][] value less than zero. +Constructor for types that include `null` as a member. -#### `NonEmpty :: Type -⁠> Type` +#### `Number :: Type` -Constructor for non-empty types. `$.NonEmpty ($.String)`, for example, is -the type comprising every [`String`][] value except `''`. +Type comprising every primitive Number value (including `NaN`). -The given type must satisfy the [Monoid][] and [Setoid][] specifications. +#### `PositiveNumber :: Type` -#### `NonGlobalRegExp :: Type` +Type comprising every [`Number`][] value greater than zero. -Type comprising every [`RegExp`][] value whose `global` flag is `false`. +#### `NegativeNumber :: Type` -See also [`GlobalRegExp`][]. +Type comprising every [`Number`][] value less than zero. -#### `NonNegativeInteger :: Type` +#### `ValidNumber :: Type` -Type comprising every non-negative [`Integer`][] value (including `-0`). -Also known as the set of natural numbers under ISO 80000-2:2009. +Type comprising every [`Number`][] value except `NaN`. + +#### `NonZeroValidNumber :: Type` -#### `NonZeroFiniteNumber :: Type` +Type comprising every [`ValidNumber`][] value except `0` and `-0`. + +#### `FiniteNumber :: Type` + +Type comprising every [`ValidNumber`][] value except `Infinity` and +`-Infinity`. + +#### `NonZeroFiniteNumber :: Type` Type comprising every [`FiniteNumber`][] value except `0` and `-0`. -#### `NonZeroInteger :: Type` +#### `PositiveFiniteNumber :: Type` -Type comprising every [`Integer`][] value except `0` and `-0`. +Type comprising every [`FiniteNumber`][] value greater than zero. -#### `NonZeroValidNumber :: Type` +#### `NegativeFiniteNumber :: Type` -Type comprising every [`ValidNumber`][] value except `0` and `-0`. +Type comprising every [`FiniteNumber`][] value less than zero. -#### `Null :: Type` +#### `Integer :: Type` -Type whose sole member is `null`. +Type comprising every integer in the range +[[`Number.MIN_SAFE_INTEGER`][min] .. [`Number.MAX_SAFE_INTEGER`][max]]. -#### `Nullable :: Type -⁠> Type` +#### `NonZeroInteger :: Type` -Constructor for types which include `null` as a member. +Type comprising every [`Integer`][] value except `0` and `-0`. -#### `Number :: Type` +#### `NonNegativeInteger :: Type` -Type comprising every primitive Number value (including `NaN`). +Type comprising every non-negative [`Integer`][] value (including `-0`). +Also known as the set of natural numbers under ISO 80000-2:2009. + +#### `PositiveInteger :: Type` + +Type comprising every [`Integer`][] value greater than zero. + +#### `NegativeInteger :: Type` + +Type comprising every [`Integer`][] value less than zero. -#### `Object :: Type` +#### `Object :: Type` Type comprising every "plain" Object value. Specifically, values created via: @@ -309,23 +356,38 @@ created via: - the `new` operator in conjunction with `Object` or a custom constructor function. -#### `PositiveFiniteNumber :: Type` +#### `Pair :: Type -⁠> Type -⁠> Type` -Type comprising every [`FiniteNumber`][] value greater than zero. +[Pair][] type constructor. -#### `PositiveInteger :: Type` +#### `RegExp :: Type` -Type comprising every [`Integer`][] value greater than zero. +Type comprising every RegExp value. -#### `PositiveNumber :: Type` +#### `GlobalRegExp :: Type` -Type comprising every [`Number`][] value greater than zero. +Type comprising every [`RegExp`][] value whose `global` flag is `true`. -#### `RegExp :: Type` +See also [`NonGlobalRegExp`][]. -Type comprising every RegExp value. +#### `NonGlobalRegExp :: Type` + +Type comprising every [`RegExp`][] value whose `global` flag is `false`. + +See also [`GlobalRegExp`][]. + +#### `StrMap :: Type -⁠> Type` + +Constructor for homogeneous Object types. -#### `RegexFlags :: Type` +`{foo: 1, bar: 2, baz: 3}`, for example, is a member of `StrMap Number`; +`{foo: 1, bar: 2, baz: 'XXX'}` is not. + +#### `String :: Type` + +Type comprising every primitive String value. + +#### `RegexFlags :: Type` Type comprising the canonical RegExp flags: @@ -338,79 +400,52 @@ Type comprising the canonical RegExp flags: - `'im'` - `'gim'` -#### `StrMap :: Type -⁠> Type` - -Constructor for homogeneous Object types. - -`{foo: 1, bar: 2, baz: 3}`, for example, is a member of `StrMap Number`; -`{foo: 1, bar: 2, baz: 'XXX'}` is not. - -#### `String :: Type` - -Type comprising every primitive String value. - -#### `Symbol :: Type` +#### `Symbol :: Type` Type comprising every Symbol value. -#### `Type :: Type` +#### `Type :: Type` Type comprising every `Type` value. -#### `TypeClass :: Type` +#### `TypeClass :: Type` Type comprising every [`TypeClass`][] value. -#### `Undefined :: Type` +#### `Undefined :: Type` Type whose sole member is `undefined`. -#### `Unknown :: Type` - -Type used to represent missing type information. The type of `[]`, -for example, is `Array ???`. - -May be used with type constructors when defining environments. Given a -type constructor `List :: Type -> Type`, one could use `List ($.Unknown)` -to include an infinite number of types in an environment: - - - `List Number` - - `List String` - - `List (List Number)` - - `List (List String)` - - `List (List (List Number))` - - `List (List (List String))` - - `...` - -#### `ValidDate :: Type` - -Type comprising every [`Date`][] value except `new Date (NaN)`. - -#### `ValidNumber :: Type` - -Type comprising every [`Number`][] value except `NaN`. - -#### `env :: Array Type` +#### `env :: Array Type` An array of [types][]: - [AnyFunction](#AnyFunction) - [Arguments](#Arguments) - - [Array](#Array) ([Unknown](#Unknown)) + - [Array](#Array) ([Unknown][]) + - [Array2](#Array2) ([Unknown][]) ([Unknown][]) - [Boolean](#Boolean) - [Date](#Date) + - [Descending](#Descending) ([Unknown][]) + - [Either](#Either) ([Unknown][]) ([Unknown][]) - [Error](#Error) + - [Fn](#Fn) ([Unknown][]) ([Unknown][]) - [HtmlElement](#HtmlElement) + - [Identity](#Identity) ([Unknown][]) + - [Maybe](#Maybe) ([Unknown][]) - [Null](#Null) - [Number](#Number) - [Object](#Object) + - [Pair](#Pair) ([Unknown][]) ([Unknown][]) - [RegExp](#RegExp) - - [StrMap](#StrMap) ([Unknown](#Unknown)) + - [StrMap](#StrMap) ([Unknown][]) - [String](#String) - [Symbol](#Symbol) + - [Type](#Type) + - [TypeClass](#TypeClass) - [Undefined](#Undefined) -#### `test :: Array Type -⁠> Type -⁠> a -⁠> Boolean` +#### `test :: Array Type -⁠> Type -⁠> a -⁠> Boolean` Takes an environment, a type, and any value. Returns `true` if the value is a member of the type; `false` otherwise. @@ -418,25 +453,11 @@ is a member of the type; `false` otherwise. The environment is only significant if the type contains [type variables][]. -One may define a more restrictive type in terms of a more general one: - -```javascript -// NonNegativeInteger :: Type -const NonNegativeInteger = $.NullaryType - ('my-package/NonNegativeInteger') - ('http://example.com/my-package#NonNegativeInteger') - (x => $.test ([]) ($.Integer) (x) && x >= 0); -``` - -Using types as predicates is useful in other contexts too. One could, -for example, define a [record type][] for each endpoint of a REST API -and validate the bodies of incoming POST requests against these types. - ### Type constructors sanctuary-def provides several functions for defining types. -#### `NullaryType :: String -⁠> String -⁠> (Any -⁠> Boolean) -⁠> Type` +#### `NullaryType :: String -⁠> String -⁠> Array Type -⁠> (Any -⁠> Boolean) -⁠> Type` Type constructor for types with no type variables (such as [`Number`][]). @@ -444,18 +465,22 @@ To define a nullary type `t` one must provide: - the name of `t` (exposed as `t.name`); - - the documentation URL of `t` (exposed as `t.url`); and + - the documentation URL of `t` (exposed as `t.url`); - - a predicate which accepts any JavaScript value and returns `true` if - (and only if) the value is a member of `t`. + - an array of supertypes (exposed as `t.supertypes`); and + + - a predicate that accepts any value that is a member of every one of + the given supertypes, and returns `true` if (and only if) the value + is a member of `t`. For example: ```javascript // Integer :: Type const Integer = $.NullaryType - ('my-package/Integer') + ('Integer') ('http://example.com/my-package#Integer') + ([]) (x => typeof x === 'number' && Math.floor (x) === x && x >= Number.MIN_SAFE_INTEGER && @@ -463,9 +488,10 @@ const Integer = $.NullaryType // NonZeroInteger :: Type const NonZeroInteger = $.NullaryType - ('my-package/NonZeroInteger') + ('NonZeroInteger') ('http://example.com/my-package#NonZeroInteger') - (x => $.test ([]) (Integer) (x) && x !== 0); + ([Integer]) + (x => x !== 0); // rem :: Integer -> NonZeroInteger -> Integer const rem = @@ -487,6 +513,8 @@ rem (0.5); // 1) 0.5 :: Number // // The value at position 1 is not a member of ‘Integer’. +// +// See http://example.com/my-package#Integer for information about the Integer type. rem (42) (0); // ! TypeError: Invalid value @@ -498,9 +526,11 @@ rem (42) (0); // 1) 0 :: Number // // The value at position 1 is not a member of ‘NonZeroInteger’. +// +// See http://example.com/my-package#NonZeroInteger for information about the NonZeroInteger type. ``` -#### `UnaryType :: String -⁠> String -⁠> (Any -⁠> Boolean) -⁠> (t a -⁠> Array a) -⁠> Type -⁠> Type` +#### `UnaryType :: Foldable f => String -⁠> String -⁠> Array Type -⁠> (Any -⁠> Boolean) -⁠> (t a -⁠> f a) -⁠> Type -⁠> Type` Type constructor for types with one type variable (such as [`Array`][]). @@ -510,14 +540,16 @@ To define a unary type `t a` one must provide: - the documentation URL of `t` (exposed as `t.url`); - - a predicate which accepts any JavaScript value and returns `true` - if (and only if) the value is a member of `t x` for some type `x`; + - an array of supertypes (exposed as `t.supertypes`); - - a function which takes any value of type `t a` and returns an array - of the values of type `a` contained in the `t` (exposed as - `t.types.$1.extractor`); and + - a predicate that accepts any value that is a member of every one of + the given supertypes, and returns `true` if (and only if) the value + is a member of `t x` for some type `x`; - - the type of `a` (exposed as `t.types.$1.type`). + - a function that takes any value of type `t a` and returns the values + of type `a` contained in the `t`; and + + - the type of `a`. For example: @@ -525,19 +557,17 @@ For example: const show = require ('sanctuary-show'); const type = require ('sanctuary-type-identifiers'); -// maybeTypeIdent :: String -const maybeTypeIdent = 'my-package/Maybe'; +// MaybeTypeRep :: TypeRep Maybe +const MaybeTypeRep = {'@@type': 'my-package/Maybe'}; // Maybe :: Type -> Type const Maybe = $.UnaryType - (maybeTypeIdent) + ('Maybe') ('http://example.com/my-package#Maybe') - (x => type (x) === maybeTypeIdent) + ([]) + (x => type (x) === MaybeTypeRep['@@type']) (maybe => maybe.isJust ? [maybe.value] : []); -// MaybeTypeRep :: TypeRep Maybe -const MaybeTypeRep = {'@@type': maybeTypeIdent}; - // Nothing :: Maybe a const Nothing = { 'constructor': MaybeTypeRep, @@ -582,7 +612,7 @@ fromMaybe (0) (Just ('XXX')); // Since there is no type of which all the above values are members, the type-variable constraint has been violated. ``` -#### `BinaryType :: String -⁠> String -⁠> (Any -⁠> Boolean) -⁠> (t a b -⁠> Array a) -⁠> (t a b -⁠> Array b) -⁠> Type -⁠> Type -⁠> Type` +#### `BinaryType :: Foldable f => String -⁠> String -⁠> Array Type -⁠> (Any -⁠> Boolean) -⁠> (t a b -⁠> f a) -⁠> (t a b -⁠> f b) -⁠> Type -⁠> Type -⁠> Type` Type constructor for types with two type variables (such as [`Array2`][]). @@ -593,41 +623,39 @@ To define a binary type `t a b` one must provide: - the documentation URL of `t` (exposed as `t.url`); - - a predicate which accepts any JavaScript value and returns `true` - if (and only if) the value is a member of `t x y` for some types - `x` and `y`; + - an array of supertypes (exposed as `t.supertypes`); + + - a predicate that accepts any value that is a member of every one of + the given supertypes, and returns `true` if (and only if) the value + is a member of `t x y` for some types `x` and `y`; - - a function which takes any value of type `t a b` and returns an array - of the values of type `a` contained in the `t` (exposed as - `t.types.$1.extractor`); + - a function that takes any value of type `t a b` and returns the + values of type `a` contained in the `t`; - - a function which takes any value of type `t a b` and returns an array - of the values of type `b` contained in the `t` (exposed as - `t.types.$2.extractor`); + - a function that takes any value of type `t a b` and returns the + values of type `b` contained in the `t`; - - the type of `a` (exposed as `t.types.$1.type`); and + - the type of `a`; and - - the type of `b` (exposed as `t.types.$2.type`). + - the type of `b`. For example: ```javascript const type = require ('sanctuary-type-identifiers'); -// pairTypeIdent :: String -const pairTypeIdent = 'my-package/Pair'; +// PairTypeRep :: TypeRep Pair +const PairTypeRep = {'@@type': 'my-package/Pair'}; // $Pair :: Type -> Type -> Type const $Pair = $.BinaryType - (pairTypeIdent) + ('Pair') ('http://example.com/my-package#Pair') - (x => type (x) === pairTypeIdent) + ([]) + (x => type (x) === PairTypeRep['@@type']) (({fst}) => [fst]) (({snd}) => [snd]); -// PairTypeRep :: TypeRep Pair -const PairTypeRep = {'@@type': pairTypeIdent}; - // Pair :: a -> b -> Pair a b const Pair = def ('Pair') @@ -642,17 +670,17 @@ def ('Pair') // Rank :: Type const Rank = $.NullaryType - ('my-package/Rank') + ('Rank') ('http://example.com/my-package#Rank') - (x => typeof x === 'string' && - /^(A|2|3|4|5|6|7|8|9|10|J|Q|K)$/.test (x)); + ([$.String]) + (x => /^(A|2|3|4|5|6|7|8|9|10|J|Q|K)$/.test (x)); // Suit :: Type const Suit = $.NullaryType - ('my-package/Suit') + ('Suit') ('http://example.com/my-package#Suit') - (x => typeof x === 'string' && - /^[\u2660\u2663\u2665\u2666]$/.test (x)); + ([$.String]) + (x => /^[\u2660\u2663\u2665\u2666]$/.test (x)); // Card :: Type const Card = $Pair (Rank) (Suit); @@ -677,9 +705,11 @@ showCard (Pair ('X') ('♠')); // 1) "X" :: String // // The value at position 1 is not a member of ‘Rank’. +// +// See http://example.com/my-package#Rank for information about the Rank type. ``` -#### `EnumType :: String -⁠> String -⁠> Array Any -⁠> Type` +#### `EnumType :: String -⁠> String -⁠> Array Any -⁠> Type` Type constructor for [enumerated types][] (such as [`RegexFlags`][]). @@ -696,18 +726,18 @@ For example: ```javascript // Denomination :: Type const Denomination = $.EnumType - ('my-package/Denomination') + ('Denomination') ('http://example.com/my-package#Denomination') ([10, 20, 50, 100, 200]); ``` -#### `RecordType :: StrMap Type -⁠> Type` +#### `RecordType :: StrMap Type -⁠> Type` -`RecordType` is used to construct record types. The type definition -specifies the name and type of each required field. A field is an -enumerable property (either an own property or an inherited property). +`RecordType` is used to construct anonymous record types. The type +definition specifies the name and type of each required field. A field is +an enumerable property (either an own property or an inherited property). -To define a record type one must provide: +To define an anonymous record type one must provide: - an object mapping field name to type. @@ -754,7 +784,64 @@ dist (0); // The value at position 1 is not a member of ‘{ x :: FiniteNumber, y :: FiniteNumber }’. ``` -#### `TypeVariable :: String -⁠> Type` +#### `NamedRecordType :: NonEmpty String -⁠> String -⁠> Array Type -⁠> StrMap Type -⁠> Type` + +`NamedRecordType` is used to construct named record types. The type +definition specifies the name and type of each required field. A field is +an enumerable property (either an own property or an inherited property). + +To define a named record type `t` one must provide: + + - the name of `t` (exposed as `t.name`); + + - the documentation URL of `t` (exposed as `t.url`); + + - an array of supertypes (exposed as `t.supertypes`); and + + - an object mapping field name to type. + +For example: + +```javascript +// Circle :: Type +const Circle = $.NamedRecordType + ('my-package/Circle') + ('http://example.com/my-package#Circle') + ([]) + ({radius: $.PositiveFiniteNumber}); + +// Cylinder :: Type +const Cylinder = $.NamedRecordType + ('Cylinder') + ('http://example.com/my-package#Cylinder') + ([Circle]) + ({height: $.PositiveFiniteNumber}); + +// volume :: Cylinder -> PositiveFiniteNumber +const volume = +def ('volume') + ({}) + ([Cylinder, $.FiniteNumber]) + (cyl => Math.PI * cyl.radius * cyl.radius * cyl.height); + +volume ({radius: 2, height: 10}); +// => 125.66370614359172 + +volume ({radius: 2}); +// ! TypeError: Invalid value +// +// volume :: Cylinder -> FiniteNumber +// ^^^^^^^^ +// 1 +// +// 1) {"radius": 2} :: Object, StrMap Number +// +// The value at position 1 is not a member of ‘Cylinder’. +// +// See http://example.com/my-package#Cylinder for information about the Cylinder type. +``` + +#### `TypeVariable :: String -⁠> Type` Polymorphism is powerful. Not being able to define a function for all types would be very limiting indeed: one couldn't even define the @@ -811,7 +898,7 @@ cmp (0) ('1'); // Since there is no type of which all the above values are members, the type-variable constraint has been violated. ``` -#### `UnaryTypeVariable :: String -⁠> Type -⁠> Type` +#### `UnaryTypeVariable :: String -⁠> Type -⁠> Type` Combines [`UnaryType`][] and [`TypeVariable`][]. @@ -819,7 +906,7 @@ To define a unary type variable `t a` one must provide: - a name (conventionally matching `^[a-z]$`); and - - the type of `a` (exposed as `t.types.$1.type`). + - the type of `a`. Consider the type of a generalized `map`: @@ -858,7 +945,7 @@ example, is `v`. One could replace `Functor => f` with `Map k` or with This shallow inspection makes it possible to constrain a value's "outer" and "inner" types independently. -#### `BinaryTypeVariable :: String -⁠> Type -⁠> Type -⁠> Type` +#### `BinaryTypeVariable :: String -⁠> Type -⁠> Type -⁠> Type` Combines [`BinaryType`][] and [`TypeVariable`][]. @@ -866,28 +953,28 @@ To define a binary type variable `t a b` one must provide: - a name (conventionally matching `^[a-z]$`); - - the type of `a` (exposed as `t.types.$1.type`); and + - the type of `a`; and - - the type of `b` (exposed as `t.types.$2.type`). + - the type of `b`. The more detailed explanation of [`UnaryTypeVariable`][] also applies to `BinaryTypeVariable`. -#### `Thunk :: Type -⁠> Type` +#### `Thunk :: Type -⁠> Type` `$.Thunk (T)` is shorthand for `$.Function ([T])`, the type comprising -every nullary function (thunk) which returns a value of type `T`. +every nullary function (thunk) that returns a value of type `T`. -#### `Predicate :: Type -⁠> Type` +#### `Predicate :: Type -⁠> Type` -`$.Predicate (T)` is shorthand for `$.Function ([T, $.Boolean])`, the -type comprising every predicate function which takes a value of type `T`. +`$.Predicate (T)` is shorthand for `$.Fn (T) ($.Boolean)`, the type +comprising every predicate function that takes a value of type `T`. ### Type classes -`concatS`, defined earlier, is a function which concatenates two strings. -This is overly restrictive, since other types support concatenation -(Array, for example). +One can trivially define a function of type `String -> String -> String` +that concatenates two strings. This is overly restrictive, though, since +other types support concatenation (`Array a`, for example). One could use a type variable to define a polymorphic "concat" function: @@ -972,10 +1059,16 @@ concat (null) (null); Multiple constraints may be placed on a type variable by including multiple `TypeClass` values in the array (e.g. `{a: [Foo, Bar, Baz]}`). +[Descending]: https://github.com/sanctuary-js/sanctuary-descending/tree/v1.1.0 +[Either]: https://github.com/sanctuary-js/sanctuary-either/tree/v1.1.0 [FL:Semigroup]: https://github.com/fantasyland/fantasy-land#semigroup [HTML element]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element +[Identity]: https://github.com/sanctuary-js/sanctuary-identity/tree/v1.1.0 +[Maybe]: https://github.com/sanctuary-js/sanctuary-maybe/tree/v1.1.0 [Monoid]: https://github.com/fantasyland/fantasy-land#monoid +[Pair]: https://github.com/sanctuary-js/sanctuary-pair/tree/v1.1.0 [Setoid]: https://github.com/fantasyland/fantasy-land#setoid +[Unknown]: #Unknown [`Array`]: #Array [`Array2`]: #Array2 [`BinaryType`]: #BinaryType @@ -1002,7 +1095,6 @@ multiple `TypeClass` values in the array (e.g. `{a: [Foo, Bar, Baz]}`). [enumerated types]: https://en.wikipedia.org/wiki/Enumerated_type [max]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER [min]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER -[record type]: #RecordType [semigroup]: https://en.wikipedia.org/wiki/Semigroup [type class]: #type-classes [type variables]: #TypeVariable diff --git a/index.js b/index.js index 7631bd3..c139a9f 100644 --- a/index.js +++ b/index.js @@ -500,7 +500,7 @@ // functionUrl :: String -> String function functionUrl(name) { - var version = '0.19.0'; // updated programmatically + var version = '0.20.0'; // updated programmatically return 'https://github.com/sanctuary-js/sanctuary-def/tree/v' + version + '#' + name; } diff --git a/package.json b/package.json index 84f51a9..67d39ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sanctuary-def", - "version": "0.19.0", + "version": "0.20.0", "description": "Run-time type system for JavaScript", "license": "MIT", "repository": {