funjsional
v0.0.4
Published
Algebraic Data Types and Haskell-like type classes for Javascript
Downloads
318
Maintainers
Readme
funJSional
funJSional provides utilities for defining algebraic data types (ADTs) and Haskell-like type classes (among other things).
A few small demonstrations:
Functional method chaining
// 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
// 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
// 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.
Install
npm i funjsional
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.
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:
// 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.
// 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:
// 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.
// 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
Types included
The following types are already defined:
- Either a b
- Enumeration a
- Maybe a
- Ordering
- Pair a b
- Ratio a
See 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:
// 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:
// 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:
// 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:
// 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.
Classes included
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 a
See class listing for more information on these classes
Runtime Nature of Classes
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, Functor
s map
has an alias defined in
'typeclasses/Functor.mjs' called _map_
. All type class property names follow
this convention, e.g. Eq
s 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 Semigroup
s 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 Rational
s. 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
andShow
type classes; and funJSional parser combinatorsInt53
Number wrapper for an alternativeIntegral
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" variants
Listings
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.
Defined Types
The following types are defined:
Either a b
//. `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
//. `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 a
//. `From :: BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration a`
//. `FromThen :: BigInt -> BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration a`
//. `FromTo :: BigInt -> BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration a`
//. `FromThenTo :: BigInt -> BigInt -> BigInt -> [ BigInt -> t0, t0 -> t1, ... tN -> a ] -> Enumeration a`
//. Static properties on type representative
//. `[Symbol.iterator] :: Enumeration a ~> <native Iterator> a`
//. Type class instances
//. `Indexed Enumeration`
Maybe a
Maybe a
is used in the return type of 'safe' variants and Enumeration
constructor
//. `Maybe a = Nothing | Just a`
//. MaybeTR - type representative for MaybeTR
//. `Nothing :: Maybe a`
//. `Just :: a -> Maybe a`
//. Static properties on type representative
//. `maybe :: b -> (a -> b) -> Maybe a -> b`
//. `fromMaybe :: 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) -> b`
//. `fromMaybe :: 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 Ord
s compare
function.
//. `Ordering = LT | EQ | GT`
//. OrderingTR - type representative for Ordering
//. `LT :: Ordering`
//. `EQ :: Ordering`
//. `GT :: Ordering`
//. Type class instances
//. `Eq Ordering`
//. `Ord Ordering`
//. `Bounded Ordering` // Strong
//. `Enum Ordering` // Strong
Pair a b
Pair a b
is used in Integral
s return types for quotRem
, quotRemTo
,
divMod
, and divModTo
. It is also used in the return type for
RealFrac
s properFraction
.
//. `Pair 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.
Note that Rational
is Ratio BigInt
. The type class definitions for
Rational
are specialized to BigInt
rather than relying on methods via the
Integral
constraint.
//. `Ratio a = { num: a, den: a }`
//. `Rational = Ratio BigInt`
//. RatioTR :: type representative for Ratio
//. `Rational :: BigInt -> BigInt -> Ratio BigInt // may throw`
//. `Ratio :: 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 BigInt`
//. `NEGATIVE_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)`
Defined Classes
The following type classes are defined:
Functor f => Alt f
//. 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
//. 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
//. Bounded a where
//. requires minBound, maxBound
//. minBound :: () -> a
//. maxBound :: () -> a
---
//. StrongBounded a where
//. requires minBound, maxBound
//. minBound :: () -> a
//. maxBound :: () -> a
Semigroupoid c => Category c
//. 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
//. Functor m => Chain m where
//. requires chain
//. chain :: m a ~> (a -> m b) -> mb
//. join :: m (m a) ~> m a
Enum a
//. 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
//. Eq a where
//. requires equals
//. equals :: a ~> a -> Boolean
//. notEquals :: a ~> a -> Boolean
Fractional a => Floating a
//. 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
//. 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
//. Functor f where
//. requires map
//. map :: f a ~> (a -> b) -> f b
//. replace :: f a ~> b -> f b
Indexed a
//. 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
//. (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
//. Semigroup a => Monoid a where
//. requires empty
//. empty :: () -> a
---
//. Semigroup a => StrongMonoid a where
//. requires empty
//. empty :: () -> a
Num a
//. 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
//. 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
//. Alt a => Plus a where
//. requires zero
//. zero :: () -> a
---
//. Alt a => StrongPlus a where
//. requires zero
//. zero :: () -> a
Pointed a
//. Pointed f where
//. requires pure
//. pure :: a -> f a
(Num a, Ord a) => Real a
//. (Num a, Ord a) => Real a where
//. requires toRational
//. toRational :: a ~> Ratio BigInt
(Real a, Fractional a) => RealFrac a
//. (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
//. Semigroup a where
//. requires append
//. append :: a ~> a -> a
//. appendTo :: a ~> a -> a
Semigroupoid a
//. 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
Extended Natives
The following native types are extended:
Array a
//. 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
//. Eq BigInt
//. Ord BigInt
//. Num BigInt // Strong
//. Enum BigInt // Strong
//. Real BigInt
//. Integral BigInt
Boolean
//. Eq Boolean
//. Ord Boolean
//. Bounded Boolean // Strong
//. Enum Boolean // Strong
Function a b
//. Semigroupoid Function
//. Category Function // Strong
//. Functor (Function a)
//. Pointed (Function a)
//. Chain (Function a)
Number
//. Eq Number
//. Ord Number
//. Num Number // Strong
//. Bounded Number // Strong
//. Enum Number // Strong
//. Real Number
//. Fractional Number // Strong
//. RealFrac Number
//. Floating Number // Strong
String
//. Eq String
//. Ord String
//. Semigroup String
//. Monoid String // Strong