Algebraic Data Types and Haskell-like type classes for Javascript
A few small demonstrations:
Functional method chaining
``javascript
// examples/01_demo1.mjs
import * as F from '../funJSional.mjs'
const { Just, Pair, _map_, _append_, _appendTo_, _chain_, _join_ } = F
console .log (
// a Pair of Just values in a Just value
Just (Pair (Just ('fun')) (Just ('JS')))
// extract Just values from the pair and append them
[_map_] (({ fst, snd }) => fst [_append_] (snd))
// join the Just Just value
[_join_] ()
// need to finish the name
[_chain_] (x => Just ('ional' [_appendTo_] (x)))
// and exclaim! (fromJust could be used here since it is a known Just)
.maybe (undefined) (x => x [_append_] ('!'))
) // => funJSional!
`
Type creation and classing with derivations
`javascript
// examples/02_demo2.mjs
import * as F from '../funJSional.mjs'
const { $_THROW_$, Type, StrongBounded, StrongEnum, _enumFrom_ } = F
// A sum type having three nullary constructors
const My123TR = Type ('My123', [
{ One : [] },
{ Two : [] },
{ Three: [] },
])
// Type constructors: One, Two, and Three
const { One, Two, Three } = My123TR
// Add Bounded and Enum type class instances
// Note that the derivations will use bounds to determine enumeration range bounds
StrongBounded (My123TR) ({
minBound: () => One,
maxBound: () => Three,
})
// only toEnum and fromEnum are required
StrongEnum (My123TR) ({
toEnum: n => n === 1n ? One :
n === 2n ? Two :
n === 3n ? Three :
$_THROW_$ (new RangeError (n must be in range [ 1n .. 3n ])),
fromEnum: {
One : () => 1n,
Two : () => 2n,
Three: () => 3n,
},
})
// and enumFrom is derived with the proper upper bound
console.log ( [ ...One [_enumFrom_] () ])
// => '[ [Function: One] One, [Function: Two] Two, [Function: Three] Three ]'
// other Enum properties are derived as well, e.g. succ, pred, enumFromThenTo, etc
`
Let's be Rational here
`javascript
// examples/03_demo3.mjs
import * as F from '../funJSional.mjs'
const { _toRational_, Rational } = F
const oneThird = 1 / 3
// Hey! oneThird is not really one-third
console .log ( oneThird ) // => 0.3333333333333333
// Let's fix that
const prettyFraction = oneThird [_toRational_] ()
const { num, den } = prettyFraction
// Now this is more like it!
console .log ( ${num} / ${den} ) // => '1 / 3'
// Here's one-third in disguise
console .log ( Rational (1328n) (3984n) ) // => Object [Rational] { num: 1n, den: 3n }
`
Notation: The function signatures used here are like those for
Fantasy Land.
Inspirations: Haskell,
Fantasy Land,
Sanctuary
Status: Experimental, active development
Support: Please![]()
if you find this project useful.
Algebraic Data Types (ADTs)
The Type function is used to create an ADT type representative. It is similar
to Daggy's taggedSum method; however,
an array is used in the second argument.
`javascript
Type ('TypeName', [
{ Constructor1Name: [ 'field1Name', 'field2Name', ...] },
{ Constructor2Name: [ 'field1Name', 'field2Name', ...] },
...
])
`
For each constructor, the type representative will have a key named for the
respective constructor name.
For example, a product type Pair with constructor Pair for a type having
fields fst and snd may be created as follows:
`javascript
// examples/04_ADT1_Pair.mjs
import { Type } from '../utility/type/Type.mjs'//.
Pair a b = { fst: a, snd: b }//. PairTR - type representative for Pair
export const PairTR = Type ('Pair', [
{ Pair: [ 'fst', 'snd' ] },
])
//. Pair :: a -> b -> Pair a b
export const { Pair } = PairTR
`
The properties are accessible via the field names.
`javascript
// 05_ADT2.mjs
import { Pair } from "./04_ADT1_Pair.mjs"const pair = Pair ('Hello') ('World')
console .log ( pair.fst ) // => "Hello"
console .log ( pair.snd ) // => "World"
`
As another example, a sum type Maybe with constructors Nothing and Just,
where Nothing has no fields and Just has a field value, may be created as
follows:
`javascript
// examples/06_ADT3_Maybe.mjs
import { Type } from '../utility/type/Type.mjs'//.
Maybe a = Nothing | Just a//. MaybeTR - type representative for MaybeTR
export const MaybeTR = Type ('Maybe', [
{ Nothing: [] },
{ Just: [ 'value' ] },
])
//.
Nothing :: Maybe a
//. Just :: a -> Maybe a
export const { Nothing, Just } = MaybeTR
`
A nullary constructor such as Nothing is a function that returns itself.
The Just constructor will create an object with a value field.
`javascript
// examples/07_ADT4.mjs
import { Just } from "./06_ADT3_Maybe.mjs"const just = Just (1)
console .log ( Nothing () === Nothing ) // => true
console .log ( just.value ) // => 1
`$3
The following types are already defined:
- Either a b
- Enumeration a
- Maybe a
- Ordering
- Pair a b
- Ratio aSee types listing for more information on these types
Type classes
The ADTs can be instances of Haskell-like type classes. For example, the
Pair and Maybe types defined above can be made instances of the
Functor class as follows:
`javascript
// examples/08_class1.mjs
import { _constructor_ } from '../utility/type/Type.mjs'
import { Functor, _map_ } from '../typeclasses/Functor.mjs'import { PairTR, Pair } from './04_ADT1_Pair.mjs'
import { MaybeTR, Nothing, Just } from './06_ADT3_Maybe.mjs'
//.
Functor (Pair a)
Functor (PairTR) ({
//. map :: Pair a b ~> (b -> c) -> Pair a c
map: {
Pair: function (f) {
return this [_constructor_] (this.fst) (f (this.snd))
},
}, //.
replace :: Pair a b ~> c -> Pair a c
replace: {
Pair: function (x) {
return this [_constructor_] (this.fst) (x)
},
},
})console .log ( Pair (1) (2) [_map_] (x => x + 1) ) // => Object [Pair] { fst: 1, snd: 3 }
//.
Functor Maybe
Functor (MaybeTR) ({
//. map :: Maybe a ~> (a -> b) -> Maybe b
map: {
Nothing: Nothing, Just: function (f) { return (
this [_constructor_] (f (this.value))
)},
},
//.
replace :: Maybe a ~> b -> Maybe b
replace: {
Nothing: Nothing, Just: function (x) { return (
this [_constructor_] (x)
)},
},
})
console .log ( Nothing [_map_] (x => x + 1) ) // => [Function: Nothing] Nothing
console .log ( Just (3) [_map_] (x => x + 1) ) // => Object [Just] { value: 4 }
`
The classes require certain properties while others may be derived. For
instance, the Functor class requires map but not replace. If replace is
not provided it will be derived. For example, the Functor instance for Pair
can be given as follows:
`javascript
// examples/09_class2.mjs
import { _constructor_ } from '../utility/type/Type.mjs'
import { Functor, _replace_ } from '../typeclasses/Functor.mjs'import { PairTR, Pair } from './04_ADT1_Pair.mjs'
//.
Functor (Pair a)
Functor (PairTR) ({
//. map :: Pair a b ~> (b -> c) -> Pair a c
map: {
Pair: function (f) {
return this [_constructor_] (this.fst) (f (this.snd))
},
},
})console .log ( Pair (1) (2) [_replace_] ('a') ) // => Object [Pair] { fst: 1, snd: "a" }
`
Some classes have properties that for a particular type are "constant". For
example, the Monoid class has the property, empty.When defining these types of properties, the definition does not require the
constructor names. For example, the
Maybe instance for Monoid can be
defined as follows:
`javascript
// examples/10_class3.mjs
import { StrongMonoid, _empty_ } from '../typeclasses/Monoid.mjs'
import { MaybeTR, Nothing } from './06_ADT3_Maybe.mjs'//.
Semigroup a => Monoid (Maybe a)
StrongMonoid (MaybeTR) ({
//. empty :: () -> Maybe a
empty: Nothing,
})console .log ( MaybeTR [_empty_] () ) // => [Function: Nothing] Nothing
`
Classes having these types of properties have two different ways of defining
instances. For example, Monoid can be defined via Monoid or StrongMonoid.
The difference is due to potential lack of type information. This can occur
for "incomplete/non-concrete" types. For example, consider the following:
`javascript
// examples/11_class4.mjs
import { Type } from '../utility/type/Type.mjs'
import { Just } from '../types/Maybe.mjs'
import { Monoid, _empty_ } from '../typeclasses/Monoid.mjs'//. Identity a = { value: a }
//. IdentityTR - type representative for Identity
const IdentityTR = Type ('Identity', [ { Identity: [ 'value' ] } ])
//. Identity :: a -> Identity a
const { Identity } = IdentityTR
//. Monoid a :: Monoid (Identity a)
Monoid (IdentityTR) ({
//. empty :: Monoid a => () -> Identity a
empty: function () { return Identity (this.value [_empty_] ()) },
})
//. empty is not found on the type representative since it cannot be always known
console .log ( IdentityTR [_empty_] ) // => undefined
//. however, for the concrete type it is known
console .log ( Identity (Just (1)) [_empty_] () )
// => Object [Identity] { value: [Function: Nothing] Nothing }
`
The Identity type is a Monoid if a is a Monoid. However, without a
concrete value for a, the empty is not known. For these situations, use the
class name, e.g. Monoid. If however, empty is known (as for the Maybe
case), then add 'Strong' to the class name, e.g. StrongMonoid.This allows for non-concrete types to have instances declared and use of the
class properties when known.
$3
The following classes are already defined
- Functor f => Alt f
- Functor f => Apply f
- Bounded a (has Strong variant)
- Category c (has Strong variant)
- Functor m => Chain m
- Enum a (has Strong variant)
- Eq a
- Fractional a => Floating a (has Strong variant)
- Num a => Fractional a (has Strong variant)
- Functor f
- Indexed i
- (Real a, Enum a) => Integral a
- Semigroup a => Monoid a (has Strong variant)
- Num a (has Strong variant)
- Ord a
- Alt a => Plus a (has Strong variant)
- Pointed a
- (Num a, Ord a) => Real a
- (Real a, Fractional a) => RealFrac a
- Semigroup a
- Semigroupoid aSee class listing for more information on these classes
$3
Since the types are made instances of type classes at runtime, the instance
must be defined prior to its use. This should not generally be a problem if the
type and class instances are defined in the same module (or function, etc).Also note that when a type is an instance of both
Bounded and Enum, the
Bounded instance should be defined prior to the Enum instance, if derivation
of Enum properties is relied upon. These are the only two classes that have
such dependency.Property Names
The properties' imparted via type class instance definitions are prefixed (See
'utility/common/PROPERTY_PREFIX.mjs'). However, they are also "aliased" via
string variable names in their respective type class files (in the 'typeclasses'
folder). For example, Functors map has an alias defined in
'typeclasses/Functor.mjs' called _map_. All type class property names follow
this convention, e.g. Eqs equals is aliased _equals_.This helps to avoid name collisions when (optionally) making native types
instances of a type class. If there is a name collision, simply change the
prefix.
Native extensions
By default (importing from funJSional.mjs) the native types Function,
String, Number, BigInt, Boolean, and Array are extended to be
members of various classes. See the native extensions listing.This is not necessary, to avoid it, import types and classes individually.
However, at this time, there are no "wrapper" types for the natives, so care
must be taken when using the "raw" natives in a container type, e.g. raw strings
contained in
Just values cannot be appended using Semigroups append
(unless the String extension is used or a suitable wrapper providing the
Semigroup instance is used).Defining Type Classes
Type classes can be defined via the Typeclass function found in
'utility/typeclass/Typeclass.mjs'.See the provided type class definitions in 'typeclasses' for examples.
TODO: expand on this
Utilities
The 'utility/aviary/' file includes all combinators of the aviary in
early-birds, "baked-in"
[not as a dependency]. Most other files found in 'utility/' are either aliases
for or curried versions of native JS functions. The most notable exception being
'utility/BigInt/' which provides utilities not provided natively (e.g. min and
max for BigInts); as well as functions needed for Rationals. The Type and
Typeclass functions are found in 'utility/type/' and 'utility/typeclass/',
respectively.TODOs, Dreams, and Wishful Thinking
Here are some desirable features/needs in no particular order:
- type constructor construction which allows for delayed evaluation types (some
preliminary work has been done on this)
- native wrappers for cases where native extension is not desired
- more robust testing (in particular, the current tests don't test "throwing"
conditions)
- more robust documentation (a funJSional [self-hosted] doc tool similar to
Transcibe would be nice)
- Fantasy Land shim
- type checking via sanctuary-def
- Read and Show type classes; and funJSional parser combinators
- Int53 Number wrapper for an alternative Integral type (emulating a 53-bit
signed integer)
- more type classes for common cases, e.g. monoidal 'Alt', applicative functor,
comonad, etc
- TODO: add definitions Type files which are using derived "safe" variantsListings
The remainder of this document is a listing of defined types
and type classes; as well as a listing of extensions to
native types.This documentation is "bare bones" at the moment, so the code will need to be
viewed to determine implementation details. Generally, the functions should have
behavior corresponding with that of their Haskell counterparts; e.g.
round
rounds "away from odd" at "mid-way" points, [ ... -1.5, -0.5, 0.5, 1.5 ...], as
does the Haskell function; as opposed to "away from -Infinity" at mid-way points as
the JS Math.round does.$3
The following types are defined:#### Either a b
`javascript
//. Either a b = Left a | Right b//. EitherTR - type representative for EitherTR
//.
Left :: a -> Either a b
//. Right :: a -> Either a b//. Static properties on type representative
//.
either :: (a -> c) -> (b -> c) -> Either a b -> c
//. fromLeft :: a -> Either a b -> a
//. fromRight :: b -> Either a b -> b
//. isLeft :: Either a b -> Boolean
//. isRight :: Either a b -> Boolean//. Instance properties
//.
either :: Either a b ~> (a -> c) -> (b -> c) -> c
//. fromLeft :: Either a b ~> a -> a
//. fromRight :: Either a b ~> b -> b
//. isLeft :: Either a b ~> Boolean
//. isRight :: Either a b ~> Boolean//. Type class instances
//.
(Eq a, Eq b) => Eq (Either a b)
//. (Ord a, Ord b) => Ord (Either a b)
//. Functor (Either a)
//. Pointed (Either a)
//. Chain (Either a)
//. Semigroup (Either a b)
`#### Enumeration a
`javascript
//. Enumeration a = { end: Maybe BigInt, mapping: [ BigInt -> t0, t0 -> t1, ... tN -> a ] }//. EnumerationTR - type representative for Enumeration
//.
Enumeration :: Maybe BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration aFrom :: BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration aFromThen :: BigInt -> BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration aFromTo :: BigInt -> BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration aFromThenTo :: BigInt -> BigInt -> BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration a//. Static properties on type representative
//. [Symbol.iterator] :: Enumeration a ~>
//. Type class instances
//. Indexed Enumeration
``
#### Maybe a
Maybe a is used in the return type of 'safe' variants and Enumeration`
constructorjavascriptMaybe a = Nothing | Just a
//.
//. MaybeTR - type representative for MaybeTR
//. Nothing :: Maybe aJust :: a -> Maybe a
//.
//. Static properties on type representative
//. maybe :: b -> (a -> b) -> Maybe a -> bfromMaybe :: a -> Maybe a -> a
//. isNothing :: Maybe a -> Boolean
//. isJust :: Maybe a -> Boolean
//. fromJust :: Maybe a -> a // may throw
//.
//. Instance properties
//. maybe :: Maybe a ~> b -> (a -> b) -> bfromMaybe :: Maybe a ~> a -> a
//. isNothing :: Maybe a ~> Boolean
//. isJust :: Maybe a ~> Boolean
//. fromJust :: Maybe a ~> a // may throw
//.
//. Type class instances
//. Eq a => Eq (Maybe a)Ord a => Ord (Maybe a)
//. Functor Maybe
//. Pointed Maybe
//. Chain Maybe
//. Semigroup a => Semigroup (Maybe a)
//. Semigroup a => Monoid (Maybe a)
//. // Strong`
#### Ordering
Ordering is the type returned by Ords compare function.`javascriptOrdering = LT | EQ | GT
//.
//. OrderingTR - type representative for Ordering
//. LT :: OrderingEQ :: Ordering
//. GT :: Ordering
//.
//. Type class instances
//. Eq OrderingOrd Ordering
//. Bounded Ordering
//. // StrongEnum Ordering
//. // Strong`
#### Pair a b
Pair a b is used in Integrals return types for quotRem, quotRemTo,divMod, and divModTo. It is also used in the return type forRealFracs properFraction.`javascriptPair a b = { fst: a, snd: b }
//.
//. PairTR - type representative for Pair
//. Pair :: a -> b -> Pair a b
//. Type class instances
//. (Eq a, Eq b) => Eq (Pair a b)(Ord a, Ord b) => Ord (Pair a b)
//. Functor (Pair a)
//. `
#### Ratio a
Ratio a is used in the Fractional, RealFrac, and Real type classes.Rational
Note that is Ratio BigInt. The type class definitions forRational are specialized to BigInt rather than relying on methods via theIntegral constraint.`javascriptRatio a = { num: a, den: a }
//. Rational = Ratio BigInt
//.
//. RatioTR :: type representative for Ratio
//. Rational :: BigInt -> BigInt -> Ratio BigInt // may throwRatio :: Integral a => a -> a -> Ratio a // may throw
//.
//. "safe" variants of constructors
//. SafeRatio :: Integral a => a -> a -> Maybe (Ratio a)SafeRational :: BigInt -> BigInt -> Maybe (Ratio BigInt)
//.
//. POSITIVE_INFINITY :: () => Ratio BigIntNEGATIVE_INFINITY :: () => Ratio BigInt
//. NaN :: () => Ratio BigInt
//.
//. Type class instances
//. Eq a => Eq (Ratio a)(Ord a, Num a) => Ord (Ratio a)
//. Integral a => Enum (Ratio a)
//. Integral a => Num (Ratio a)
//. Integral a => Real (Ratio a)
//. Integral a => Fractional (Ratio a)
//. Integral a => RealFrac (Ratio a)
//. `
The following type classes are defined:
#### Functor f => Alt f
`javascript`
//. Functor f => Alt f where
//. requires alt
//. alt :: f a ~> f a -> f a
//. altTo :: f a ~> f a -> f a
#### Functor f => Apply f
`javascript`
//. Functor f => Apply f where
//. requires ap
//. ap :: Functor f => f a ~> f (a -> b) -> f b
//. apTo :: Functor f => f (a -> b) ~> f a -> f b
//. keep :: Functor f => f a ~> f b -> f b
//. discard :: Functor f => f a ~> f b -> f a
#### Bounded a
`javascript
//. Bounded a where
//. requires minBound, maxBound
//. minBound :: () -> a
//. maxBound :: () -> a
---
//. StrongBounded a where
//. requires minBound, maxBound
//. minBound :: () -> a
//. maxBound :: () -> a
`
#### Semigroupoid c => Category c
`javascript
//. Semigroupoid c => Category c where
//. requires id
//. id :: () -> c a a
---
//. Semigroupoid c => StrongCategory c where
//. requires id
//. id :: () -> c a a
`
#### Functor m => Chain m
`javascript`
//. Functor m => Chain m where
//. requires chain
//. chain :: m a ~> (a -> m b) -> mb
//. join :: m (m a) ~> m a
#### Enum a
`javascript
//. Enum a where
//. requires toEnum, fromEnum
//. toEnum :: BigInt -> a // may throw
//. safeToEnum :: BigInt -> Maybe a
//. fromEnum :: a ~> BigInt
//. succ :: a ~> a // may throw
//. safeSucc :: a ~> Maybe a
//. pred :: a ~> a // may throw
//. safePred :: a ~> Maybe a
//. enumFrom :: a ~> Enumeration a
//. enumFromThen :: a ~> a -> Enumeration a
//. enumFromTo :: a ~> a -> Enumeration a
//. enumFromThenTo :: a ~> a -> a -> Enumeration a
---
//. StrongEnum a where
//. requires toEnum, fromEnum
//. toEnum :: BigInt -> a // may throw
//. safeToEnum :: BigInt -> Maybe a
//. fromEnum :: a ~> BigInt
//. succ :: a ~> a // may throw
//. safeSucc :: a ~> Maybe a
//. pred :: a ~> a // may throw
//. safePred :: a ~> Maybe a
//. enumFrom :: a ~> Enumeration a
//. enumFromThen :: a ~> a -> Enumeration a
//. enumFromTo :: a ~> a -> Enumeration a
//. enumFromThenTo :: a ~> a -> a -> Enumeration a
`
#### Eq a
`javascript`
//. Eq a where
//. requires equals
//. equals :: a ~> a -> Boolean
//. notEquals :: a ~> a -> Boolean
#### Fractional a => Floating a
`javascript
//. Fractional a => Floating a where
//. requires pi, exp, log, sin, cos, asin, acos, atan, sinh, cosh,
//. asinh, acosh, atanh
//. pi :: () -> a
//. exp :: a ~> a
//. log :: a ~> a
//. sqrt :: a ~> a
//. antilog :: a ~> a -> a
//. antilogTo :: a ~> a -> a
//. logBase :: a ~> a -> a
//. logBaseTo :: a ~> a -> a
//. sin :: a ~> a
//. cos :: a ~> a
//. tan :: a ~> a
//. asin :: a ~> a
//. acos :: a ~> a
//. atan :: a ~> a
//. sinh :: a ~> a
//. cosh :: a ~> a
//. tanh :: a ~> a
//. asinh :: a ~> a
//. acosh :: a ~> a
//. atanh :: a ~> a
---
//. Fractional a => StrongFloating a where
//. requires pi, exp, log, sin, cos, asin, acos, atan, sinh, cosh,
//. asinh, acosh, atanh
//. pi :: () -> a
//. exp :: a ~> a
//. log :: a ~> a
//. sqrt :: a ~> a
//. antilog :: a ~> a -> a
//. antilogTo :: a ~> a -> a
//. logBase :: a ~> a -> a
//. logBaseTo :: a ~> a -> a
//. sin :: a ~> a
//. cos :: a ~> a
//. tan :: a ~> a
//. asin :: a ~> a
//. acos :: a ~> a
//. atan :: a ~> a
//. sinh :: a ~> a
//. cosh :: a ~> a
//. tanh :: a ~> a
//. asinh :: a ~> a
//. acosh :: a ~> a
//. atanh :: a ~> a
`
#### Num a => Fractional a
`javascript
//. Num a => Fractional a where
//. requires recip, fromRational
//. recip :: a ~> a // may throw
//. safeRecip :: a ~> Maybe a
//. dividedBy :: a ~> a -> a // may throw
//. safeDividedBy :: a ~> a -> Maybe a
//. dividing :: a ~> a -> a // may throw
//. safeDividing :: a ~> a -> Maybe a
//. fromRational :: Ratio BigInt -> a // may throw
//. safeFromRational :: Ratio BigInt -> Maybe a
---
//. Num a => StrongFractional a where
//. requires recip, fromRational
//. recip :: a ~> a // may throw
//. safeRecip :: a ~> Maybe a
//. dividedBy :: a ~> a -> a // may throw
//. safeDividedBy :: a ~> a -> Maybe a
//. dividing :: a ~> a -> a // may throw
//. safeDividing :: a ~> a -> Maybe a
//. fromRational :: Ratio BigInt -> a // may throw
//. safeFromRational :: Ratio BigInt -> Maybe a
`
#### Functor a
`javascript`
//. Functor f where
//. requires map
//. map :: f a ~> (a -> b) -> f b
//. replace :: f a ~> b -> f b`
#### Indexed ajavascript`
//. Indexed I where
//. requires at, size
//. at :: I a ~> BigInt -> a // may throw
//. at :: I a ~> BigInt -> Maybe a
//. size :: I a ~> BigInt // may throw
//. size :: I a ~> Maybe BigInt
// return Nothing if I a is not bounded
#### (Real a, Enum a) => Integral a
`javascript`
//. (Real a, Enum a) => Integral a where
//. requires quotRem, toBigInt
//. quot :: a ~> a -> a // may throw
//. safeQuot :: a ~> a -> Maybe a
//. quotTo :: a ~> a -> a // may throw
//. safeQuotTo :: a ~> a -> Maybe a
//. rem :: a ~> a -> a // may throw
//. safeRem :: a ~> a -> Maybe a
//. remTo :: a ~> a -> a // may throw
//. safeRemTo :: a ~> a -> Maybe a
//. div :: a ~> a -> a // may throw
//. safeDiv :: a ~> a -> Maybe a
//. divTo :: a ~> a -> a // may throw
//. safeDivTo :: a ~> a -> Maybe a
//. mod :: a ~> a -> a // may throw
//. safeMod :: a ~> a -> Maybe a
//. modTo :: a ~> a -> a // may throw
//. safeModTo :: a ~> a -> Maybe a
//. quotRem :: a ~> a -> Pair a a // may throw
//. safeQuotRem :: a ~> a -> Maybe (Pair a a)
//. quotRemTo :: a ~> a -> Pair a a // may throw
//. safeQuotRemTo :: a ~> a -> Maybe (Pair a a)
//. divMod :: a ~> a -> Pair a a // may throw
//. safeDivMod :: a ~> a -> Maybe (Pair a a)
//. divModTo :: a ~> a -> Pair a a // may throw
//. safeDivModTo :: a ~> a -> Maybe (Pair a a)
//. toBigInt :: a ~> BigInt
#### Semigroup a => Monoid a
`javascript
//. Semigroup a => Monoid a where
//. requires empty
//. empty :: () -> a
---
//. Semigroup a => StrongMonoid a where
//. requires empty
//. empty :: () -> a
`
#### Num a
`javascript
//. Num a where
//. requires plus, minus, times, abs, signum, fromBigInt
//. plus :: a ~> a -> a
//. minus :: a ~> a -> a
//. minusTo :: a ~> a -> a
//. times:: a ~> a -> a
//. abs :: a ~> a
//. signum :: a ~> a
//. negate :: a ~> a
//. fromBigInt :: BigInt -> a
---
//. StrongNum a where
//. requires plus, minus, times, abs, signum, fromBigInt
//. plus :: a ~> a -> a
//. minus :: a ~> a -> a
//. minusTo :: a ~> a -> a
//. times:: a ~> a -> a
//. abs :: a ~> a
//. signum :: a ~> a
//. negate :: a ~> a
//. fromBigInt :: BigInt -> a
`
#### Ord a
`javascript`
//. Ord a where
//. requires compare
//. compare :: a ~> a -> Ordering
//. gte :: a ~> a -> Boolean
//. lt :: a ~> a -> Boolean
//. lte :: a ~> a -> Boolean
//. gt :: a ~> a -> Boolean
//. min :: a ~> a -> a
//. max :: a ~> a -> a
#### Alt a => Plus a
`javascript`
//. Alt a => Plus a where
//. requires zero
//. zero :: () -> a
---
//. Alt a => StrongPlus a where
//. requires zero
//. zero :: () -> a
#### Pointed a
`javascript`
//. Pointed f where
//. requires pure
//. pure :: a -> f a
#### (Num a, Ord a) => Real a
`javascript`
//. (Num a, Ord a) => Real a where
//. requires toRational
//. toRational :: a ~> Ratio BigInt
#### (Real a, Fractional a) => RealFrac a
`javascript`
//. (Real a, Fractional a) => RealFrac a where
//. requires properFraction
//. properFraction :: Integral b => a ~> Pair b a
//. truncate :: Integral b => a ~> b
//. round :: Integral b => a ~> b
//. ceiling :: Integral b => a ~> b
//. floor :: Integral b => a ~> b
#### Semigroup a
`javascript`
//. Semigroup a where
//. requires append
//. append :: a ~> a -> a
//. appendTo :: a ~> a -> a
#### Semigroupoid a
`javascript`
//. Semigroupoid s where
//. requires compose
//. compose :: s a b ~> s b c -> s a c
//. composeTo :: s b c ~> s a b -> s a c
#### Array a
`javascript`
//. type class instances
//. Eq a => Eq (Array a)
//. Ord a => Ord (Array a)
//. Functor Array
//. Pointed Array
//. Chain Array
//. Semigroup Array
//. Monoid Array // Strong
//. Indexed Array
#### BigInt
`javascript`
//. Eq BigInt
//. Ord BigInt
//. Num BigInt // Strong
//. Enum BigInt // Strong
//. Real BigInt
//. Integral BigInt
#### Boolean
`javascript`
//. Eq Boolean
//. Ord Boolean
//. Bounded Boolean // Strong
//. Enum Boolean // Strong
#### Function a b
`javascript`
//. Semigroupoid Function
//. Category Function // Strong
//. Functor (Function a)
//. Pointed (Function a)
//. Chain (Function a)
#### Number
`javascript`
//. Eq Number
//. Ord Number
//. Num Number // Strong
//. Bounded Number // Strong
//. Enum Number // Strong
//. Real Number
//. Fractional Number // Strong
//. RealFrac Number
//. Floating Number // Strong
#### String
`javascript``
//. Eq String
//. Ord String
//. Semigroup String
//. Monoid String // Strong