Socket
Socket
Sign inDemoInstall

sanctuary-type-classes

Package Overview
Dependencies
1
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    sanctuary-type-classes

Standard library for Fantasy Land


Version published
Weekly downloads
53K
decreased by-26.67%
Maintainers
1
Install size
81.4 kB
Created
Weekly downloads
 

Readme

Source

sanctuary-type-classes

The Fantasy Land Specification "specifies interoperability of common algebraic structures" by defining a number of type classes. For each type class, it states laws which every member of a type must obey in order for the type to be a member of the type class. In order for the Maybe type to be considered a Functor, for example, every Maybe a value must have a fantasy-land/map method which obeys the identity and composition laws.

This project provides:

  • TypeClass, a function for defining type classes;
  • one TypeClass value for each Fantasy Land type class;
  • lawful Fantasy Land methods for JavaScript's built-in types;
  • one function for each Fantasy Land method; and
  • several functions derived from these functions.

Type-class hierarchy

 Setoid   Semigroup   Foldable        Functor
(equals)   (concat)   (reduce)         (map)
              |           \         / | | | | \
              |            \       /  | | | |  \
              |             \     /   | | | |   \
              |              \   /    | | | |    \
              |               \ /     | | | |     \
           Monoid         Traversable | | | |      \
           (empty)        (traverse)  / | | \       \
                                     /  | |  \       \
                                    /   / \   \       \
                            Profunctor /   \ Bifunctor \
                             (promap) /     \ (bimap)   \
                                     /       \           \
                                    /         \           \
                                  Alt        Apply      Extend
                                 (alt)        (ap)     (extend)
                                  /           / \           \
                                 /           /   \           \
                                /           /     \           \
                               /           /       \           \
                              /           /         \           \
                            Plus    Applicative    Chain      Comonad
                           (zero)       (of)      (chain)    (extract)
                              \         / \         / \
                               \       /   \       /   \
                                \     /     \     /     \
                                 \   /       \   /       \
                                  \ /         \ /         \
                              Alternative    Monad     ChainRec
                                                      (chainRec)

API

TypeClass :: (String, Array TypeClass, a -> Boolean) -> TypeClass

The arguments are:

  • the name of the type class, prefixed by its npm package name;
  • an array of dependencies; and
  • a predicate which accepts any JavaScript value and returns true if the value satisfies the requirements of the type class; false otherwise.

Example:

//    hasMethod :: String -> a -> Boolean
const hasMethod = name => x => x != null && typeof x[name] == 'function';

//    Foo :: TypeClass
const Foo = Z.TypeClass('my-package/Foo', [], hasMethod('foo'));

//    Bar :: TypeClass
const Bar = Z.TypeClass('my-package/Bar', [Foo], hasMethod('bar'));

Types whose values have a foo method are members of the Foo type class. Members of the Foo type class whose values have a bar method are also members of the Bar type class.

Each TypeClass value has a test field: a function which accepts any JavaScript value and returns true if the value satisfies the type class's predicate and the predicates of all the type class's dependencies; false otherwise.

TypeClass values may be used with sanctuary-def to define parametrically polymorphic functions which verify their type-class constraints at run time.

Setoid :: TypeClass

TypeClass value for Setoid.

> Setoid.test(null)
true
Semigroup :: TypeClass

TypeClass value for Semigroup.

> Semigroup.test('')
true

> Semigroup.test(0)
false
Monoid :: TypeClass

TypeClass value for Monoid.

> Monoid.test('')
true

> Monoid.test(0)
false
Functor :: TypeClass

TypeClass value for Functor.

> Functor.test([])
true

> Functor.test('')
false
Bifunctor :: TypeClass

TypeClass value for Bifunctor.

> Bifunctor.test(Tuple('foo', 64))
true

> Bifunctor.test([])
false
Profunctor :: TypeClass

TypeClass value for Profunctor.

> Profunctor.test(Math.sqrt)
true

> Profunctor.test([])
false
Apply :: TypeClass

TypeClass value for Apply.

> Apply.test([])
true

> Apply.test({})
false
Applicative :: TypeClass

TypeClass value for Applicative.

> Applicative.test([])
true

> Applicative.test({})
false
Chain :: TypeClass

TypeClass value for Chain.

> Chain.test([])
true

> Chain.test({})
false
ChainRec :: TypeClass

TypeClass value for ChainRec.

> ChainRec.test([])
true

> ChainRec.test({})
false
Monad :: TypeClass

TypeClass value for Monad.

> Monad.test([])
true

> Monad.test({})
false
Alt :: TypeClass

TypeClass value for Alt.

> Alt.test({})
true

> Alt.test('')
false
Plus :: TypeClass

TypeClass value for Plus.

> Plus.test({})
true

> Plus.test('')
false
Alternative :: TypeClass

TypeClass value for Alternative.

> Alternative.test([])
true

> Alternative.test({})
false
Foldable :: TypeClass

TypeClass value for Foldable.

> Foldable.test({})
true

> Foldable.test('')
false
Traversable :: TypeClass

TypeClass value for Traversable.

> Traversable.test([])
true

> Traversable.test({})
false
Extend :: TypeClass

TypeClass value for Extend.

> Extend.test([])
true

> Extend.test({})
false
Comonad :: TypeClass

TypeClass value for Comonad.

> Comonad.test(Identity(0))
true

> Comonad.test([])
false
toString :: a -> String

Returns a useful string representation of its argument.

Dispatches to the argument's toString method if appropriate.

Where practical, equals(eval(toString(x)), x) = true.

toString implementations are provided for the following built-in types: Null, Undefined, Boolean, Number, Date, String, Array, Arguments, Error, and Object.

> toString(-0)
'-0'

> toString(['foo', 'bar', 'baz'])
'["foo", "bar", "baz"]'

> toString({x: 1, y: 2, z: 3})
'{"x": 1, "y": 2, "z": 3}'

> toString(Cons(1, Cons(2, Cons(3, Nil))))
'Cons(1, Cons(2, Cons(3, Nil)))'
equals :: (a, b) -> Boolean

Returns true if its arguments are of the same type and equal according to the type's fantasy-land/equals method; false otherwise.

fantasy-land/equals implementations are provided for the following built-in types: Null, Undefined, Boolean, Number, Date, RegExp, String, Array, Arguments, Error, Object, and Function.

The algorithm supports circular data structures. Two arrays are equal if they have the same index paths and for each path have equal values. Two arrays which represent [1, [1, [1, [1, [1, ...]]]]], for example, are equal even if their internal structures differ. Two objects are equal if they have the same property paths and for each path have equal values.

> equals(0, -0)
false

> equals(NaN, NaN)
true

> equals(Cons('foo', Cons('bar', Nil)), Cons('foo', Cons('bar', Nil)))
true

> equals(Cons('foo', Cons('bar', Nil)), Cons('bar', Cons('foo', Nil)))
false
concat :: Semigroup a => (a, a) -> a

Function wrapper for fantasy-land/concat.

fantasy-land/concat implementations are provided for the following built-in types: String, Array, and Object.

> concat('abc', 'def')
'abcdef'

> concat([1, 2, 3], [4, 5, 6])
[1, 2, 3, 4, 5, 6]

> concat({x: 1, y: 2}, {y: 3, z: 4})
{x: 1, y: 3, z: 4}

> concat(Cons('foo', Cons('bar', Cons('baz', Nil))), Cons('quux', Nil))
Cons('foo', Cons('bar', Cons('baz', Cons('quux', Nil))))
empty :: Monoid m => TypeRep m -> m

Function wrapper for fantasy-land/empty.

fantasy-land/empty implementations are provided for the following built-in types: String, Array, and Object.

> empty(String)
''

> empty(Array)
[]

> empty(Object)
{}

> empty(List)
Nil
map :: Functor f => (a -> b, f a) -> f b

Function wrapper for fantasy-land/map.

fantasy-land/map implementations are provided for the following built-in types: Array, Object, and Function.

> map(Math.sqrt, [1, 4, 9])
[1, 2, 3]

> map(Math.sqrt, {x: 1, y: 4, z: 9})
{x: 1, y: 2, z: 3}

> map(Math.sqrt, s => s.length)('Sanctuary')
3

> map(Math.sqrt, Tuple('foo', 64))
Tuple('foo', 8)

> map(Math.sqrt, Nil)
Nil

> map(Math.sqrt, Cons(1, Cons(4, Cons(9, Nil))))
Cons(1, Cons(2, Cons(3, Nil)))
bimap :: Bifunctor f => (a -> b, c -> d, f a c) -> f b d

Function wrapper for fantasy-land/bimap.

> bimap(s => s.toUpperCase(), Math.sqrt, Tuple('foo', 64))
Tuple('FOO', 8)
promap :: Profunctor p => (a -> b, c -> d, p b c) -> p a d

Function wrapper for fantasy-land/promap.

fantasy-land/promap implementations are provided for the following built-in types: Function.

> promap(Math.abs, x => x + 1, Math.sqrt)(-100)
11
ap :: Apply f => (f (a -> b), f a) -> f b

Function wrapper for fantasy-land/ap.

fantasy-land/ap implementations are provided for the following built-in types: Array and Function.

> ap([Math.sqrt, x => x * x], [1, 4, 9, 16, 25])
[1, 2, 3, 4, 5, 1, 16, 81, 256, 625]

> ap(s => n => s.slice(0, n), s => Math.ceil(s.length / 2))('Haskell')
'Hask'

> ap(Identity(Math.sqrt), Identity(64))
Identity(8)

> ap(Cons(Math.sqrt, Cons(x => x * x, Nil)), Cons(16, Cons(100, Nil)))
Cons(4, Cons(10, Cons(256, Cons(10000, Nil))))
lift2 :: Apply f => (a -> b -> c, f a, f b) -> f c

Lifts a -> b -> c to Apply f => f a -> f b -> f c and returns the result of applying this to the given arguments.

This function is derived from map and ap.

See also lift3.

> lift2(x => y => Math.pow(x, y), [10], [1, 2, 3])
[10, 100, 1000]

> lift2(x => y => Math.pow(x, y), Identity(10), Identity(3))
Identity(1000)
lift3 :: Apply f => (a -> b -> c -> d, f a, f b, f c) -> f d

Lifts a -> b -> c -> d to Apply f => f a -> f b -> f c -> f d and returns the result of applying this to the given arguments.

This function is derived from map and ap.

See also lift2.

> lift3(x => y => z => x + z + y, ['<'], ['>'], ['foo', 'bar', 'baz'])
['<foo>', '<bar>', '<baz>']

> lift3(x => y => z => x + z + y, Identity('<'), Identity('>'), Identity('baz'))
Identity('<baz>')
apFirst :: Apply f => (f a, f b) -> f a

Combines two effectful actions, keeping only the result of the first. Equivalent to Haskell's (<*) function.

This function is derived from lift2.

See also apSecond.

> apFirst([1, 2], [3, 4])
[1, 1, 2, 2]

> apFirst(Identity(1), Identity(2))
Identity(1)
apSecond :: Apply f => (f a, f b) -> f b

Combines two effectful actions, keeping only the result of the second. Equivalent to Haskell's (*>) function.

This function is derived from lift2.

See also apFirst.

> apSecond([1, 2], [3, 4])
[3, 4, 3, 4]

> apSecond(Identity(1), Identity(2))
Identity(2)
of :: Applicative f => (TypeRep f, a) -> f a

Function wrapper for fantasy-land/of.

fantasy-land/of implementations are provided for the following built-in types: Array and Function.

> of(Array, 42)
[42]

> of(Function, 42)(null)
42

> of(List, 42)
Cons(42, Nil)
chain :: Chain m => (a -> m b, m a) -> m b

Function wrapper for fantasy-land/chain.

fantasy-land/chain implementations are provided for the following built-in types: Array and Function.

> chain(x => [x, x], [1, 2, 3])
[1, 1, 2, 2, 3, 3]

> chain(x => x % 2 == 1 ? of(List, x) : Nil, Cons(1, Cons(2, Cons(3, Nil))))
Cons(1, Cons(3, Nil))

> chain(n => s => s.slice(0, n), s => Math.ceil(s.length / 2))('Haskell')
'Hask'
join :: Chain m => m (m a) -> m a

Removes one level of nesting from a nested monadic structure.

This function is derived from chain.

> join([[1], [2], [3]])
[1, 2, 3]

> join([[[1, 2, 3]]])
[[1, 2, 3]]

> join(Identity(Identity(1)))
Identity(1)
chainRec :: ChainRec m => (TypeRep m, (a -> c, b -> c, a) -> m c, a) -> m b

Function wrapper for fantasy-land/chainRec.

fantasy-land/chainRec implementations are provided for the following built-in types: Array.

> chainRec(
.   Array,
.   (next, done, s) => s.length == 2 ? [s + '!', s + '?'].map(done)
.                                    : [s + 'o', s + 'n'].map(next),
.   ''
. )
['oo!', 'oo?', 'on!', 'on?', 'no!', 'no?', 'nn!', 'nn?']
filter :: (Applicative f, Foldable f, Monoid (f a)) => (a -> Boolean, f a) -> f a

Filters its second argument in accordance with the given predicate.

This function is derived from empty, of, and reduce.

See also filterM.

> filter(x => x % 2 == 1, [1, 2, 3])
[1, 3]

> filter(x => x % 2 == 1, Cons(1, Cons(2, Cons(3, Nil))))
Cons(1, Cons(3, Nil))
filterM :: (Monad m, Monoid (m a)) => (a -> Boolean, m a) -> m a

Filters its second argument in accordance with the given predicate.

This function is derived from empty, of, and chain.

See also filter.

> filterM(x => x % 2 == 1, [1, 2, 3])
[1, 3]

> filterM(x => x % 2 == 1, Cons(1, Cons(2, Cons(3, Nil))))
Cons(1, Cons(3, Nil))
alt :: Alt f => (f a, f a) -> f a

Function wrapper for fantasy-land/alt.

fantasy-land/alt implementations are provided for the following built-in types: Array and Object.

> alt([1, 2, 3], [4, 5, 6])
[1, 2, 3, 4, 5, 6]

> alt(Nothing, Nothing)
Nothing

> alt(Nothing, Just(1))
Just(1)

> alt(Just(2), Just(3))
Just(2)
zero :: Plus f => TypeRep f -> f a

Function wrapper for fantasy-land/zero.

fantasy-land/zero implementations are provided for the following built-in types: Array and Object.

> zero(Array)
[]

> zero(Object)
{}

> zero(Maybe)
Nothing
reduce :: Foldable f => ((b, a) -> b, b, f a) -> b

Function wrapper for fantasy-land/reduce.

fantasy-land/reduce implementations are provided for the following built-in types: Array and Object.

> reduce((xs, x) => [x].concat(xs), [], [1, 2, 3])
[3, 2, 1]

> reduce(concat, '', Cons('foo', Cons('bar', Cons('baz', Nil))))
'foobarbaz'
traverse :: (Applicative f, Traversable t) => (a -> f a, b -> f c, t b) -> f (t c)

Function wrapper for fantasy-land/traverse.

fantasy-land/traverse implementations are provided for the following built-in types: Array.

See also sequence.

> traverse(x => [x], x => x, [[1, 2, 3], [4, 5]])
[[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]

> traverse(Identity, x => Identity(x + 1), [1, 2, 3])
Identity([2, 3, 4])
sequence :: (Applicative f, Traversable t) => (a -> f a, t (f b)) -> f (t b)

Inverts the given t (f b) to produce an f (t b).

This function is derived from traverse.

> sequence(x => [x], Identity([1, 2, 3]))
[Identity(1), Identity(2), Identity(3)]

> sequence(Identity, [Identity(1), Identity(2), Identity(3)])
Identity([1, 2, 3])
extend :: Extend w => (w a -> b, w a) -> w b

Function wrapper for fantasy-land/extend.

fantasy-land/extend implementations are provided for the following built-in types: Array.

> extend(xs => xs.length, ['foo', 'bar', 'baz', 'quux'])
[4]
extract :: Comonad w => w a -> a

Function wrapper for fantasy-land/extract.

> extract(Identity(42))
42

FAQs

Last updated on 27 Dec 2016

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc