npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

funjsional

v0.0.4

Published

Algebraic Data Types and Haskell-like type classes for Javascript

Downloads

318

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, 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" 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 Ords 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 Integrals return types for quotRem, quotRemTo, divMod, and divModTo. It is also used in the return type for RealFracs 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