An extensible implementation of the Maybe type for functional programming
npm install @oncomouse/call-me-maybeThis library is an implementation of the Maybe ADT based on Fantasy Land's daggy implementation.
Folktale contains a very good implementation of the Maybe type, but it does not implement Fantasy Land's Alt specification. Additionally, Folktale's Maybe type is not easily extended, so I wrote this one, using daggy, which uses plain objects to build ADTs and is therefore very extensible.
To install, run:
~~~bash
npm install @oncomouse/call-me-maybe
~~~
Or
~~~bash
yarn add @oncomouse/call-me-maybe
~~~
You can now run require('@oncomouse/call-me-maybe') to access the library.
You can also include the library in web pages using unpkg:
~~~html
~~~
This file includes the full environment needed to use the Maybe type in your projects.
This library uses epoberezkin/fast-deep-equals for equality checking. It is an ok (and small) implementation. Lodash, Ramda, and Sanctuary's equality methods are all around 40K, which is a lot to implement Setoid. If, however, you want to use a different library, you can add it to Maybe by re-assigning the value of Maybe._equals. For instance:
~~~javascript
var Maybe = require('@oncomouse/call-me-maybe');
var {equals} = require('ramda');
Maybe._equals = equals; // Now using Ramda's equality check
~~~
Take a look at this explanation from Fantasy Land for information on reading the function type signatures below.
The following methods are applied to the Typeclass itself:
~~~javascript
Maybe.of(5) // Maybe.Just(5)
Maybe.empty() // Maybe.Nothing
Maybe.zero() // Maybe.Nothing
~~~
#### of Method
Return a Maybe.Just instance containing the supplied data.
~~~haskell
of :: Maybe f => a -> f a
~~~
#### empty Method
Return the empty (Maybe.Nothing) version of this type.
~~~haskell
empty :: Nothing
~~~
#### zero Method
Return the zero (Maybe.Nothing) version of this type.
~~~haskell
zero :: Nothing
~~~
The following methods are available to members of the type:
~~~javascript
var a = Maybe.Just(7)
var b = Maybe.Just(6)
var f = Maybe.of(x => x + 4)
a.equals(b) // false
a.map(x => x + 2) // Maybe.Just(9)
f.apply(a) // Maybe.Just(11)
a.ap(f) // Maybe.Just(11)
a.chain(x => Maybe.of(x+4)) // Maybe.Just(11)
a.unsafeGet() // 7
Maybe.Nothing.unsafeGet() // Error
a.getOrElse(5) // 7
Maybe.Nothing.getOrElse(5) // 5
Maybe.of([]).concat(Maybe.of([5])) // [5]
Maybe.Nothing.fold(() => Maybe.Just(false), x => Maybe.Just(x + 1)) // Maybe.Just(false)
a.filter(x => x < 5) // Maybe.Nothing
Maybe.Nothing.alt(a) // Maybe.Just(7)
~~~
#### equals Method
Compare the equality of one Maybe with another.
~~~haskell
equals :: Maybe f => f a ~> f b -> Boolean
~~~
#### map Method
Apply a transformation function to a Maybe.
The transformation function does not itself return a Maybe.
~~~haskell
map :: Maybe f => f a ~> (a -> b) -> f b
~~~
#### apply Method
Called on a Maybe that contains a function with a Maybe that contains a value, return the Maybe that holds the result of the function applied to the value.
~~~haskell
apply :: Maybe f => f (a -> b) ~> f a -> f b
~~~
#### ap Method
Called on a Maybe that contains a value with a Maybe that contains a function, return the Maybe that holds the result of the function applied to the value.
~~~haskell
ap :: Maybe f => f a ~> f (a -> b) -> f b
~~~
#### chain Method
Called on a Maybe that contains a value with a function that takes a value and returns a Maybe, return the result of that function.
~~~haskell
chain :: Maybe f => f a ~> (a -> f b) -> f b
~~~
#### unsafeGet Method
Get the value of a Maybe but will throw an error if called on Maybe.Nothing.
~~~haskell
unsafeGet :: Maybe f => f a ~> a
~~~
#### getOrElse Method
Called on a Maybe that contains a value with another value, return the value of the Maybe or the default value if the Maybe is Maybe.Nothing.
~~~haskell
getOrElse :: Maybe f => f a ~> a -> a
~~~
#### concat Method
Called on a Maybe whose value has a concat() or a fantasy-land/concat() method with another maybe containing the same kind of value, return a Maybe containing the result of concatenating the second value to the first.
~~~haskell
concat :: Maybe f => f a ~> f a -> f a
~~~
#### fold Method
Called on a Maybe with two functions, return the result of the first if the Maybe is Maybe.Nothing and a Maybe with the result of the second function applied to the value of the Maybe.
~~~haskell
fold :: Maybe f => f a ~> (_ -> f b) -> (a -> f b) -> f b
~~~
#### filter Method
Called on a Maybe and function that takes a value and returns a Boolean, either return the Maybe or Maybe.Nothing if the Boolean is false.
~~~haskell
filter :: Maybe f => f a ~> (a -> Boolean) -> f a
~~~
#### alt Method
Called on a Maybe with another Maybe, return the first Maybe unless the first is Maybe.Nothing, in which case return the second Maybe.
~~~haskell
alt :: Maybe f => f a ~> f a -> f a
~~~
The following methods from the API have Fantasy Land compliant equivalents:
* of -> fantasy-land/of
* empty -> fantasy-land/empty
* zero -> fantasy-land/zero
* equals -> fantasy-land/equals
* map -> fantasy-land/map
* ap -> fantasy-land/ap
* chain -> fantasy-land/chain
* concat -> fantasy-land/concat
* filter -> fantasy-land/filter
* alt -> fantasy-land/alt
So, for instance:
~~~javascript
equals(
Maybe.of([6]).concat(Maybe.of[7])
, Maybe'fantasy-land/of''fantasy-land/concat')
) === true
~~~
This library implements the following Fantasy Land specifications:
* Setoid
* Semigroup
* Monoid
* Filterable
* Functor
* Apply
* Applicative
* Alt
* Plus
* Alternative
* Chain
* Monad