Skip to content

Commit

Permalink
(doc) Documentation for Data.Maybe
Browse files Browse the repository at this point in the history
  • Loading branch information
robotlolita committed Jan 7, 2017
1 parent 6154387 commit 47a03dd
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 20 deletions.
121 changes: 121 additions & 0 deletions docs/source/en/data/maybe/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,124 @@ requirement of having to return a Maybe::
Nothing: () => 'Nothing was found'
});
// ==> 'Nothing was found'


@annotate: folktale.data.maybe.Nothing
---

Constructs a Maybe value that represents a failure (a `Nothing`).

See the documentation for the Maybe structure to understand how to use this.


@annotate: folktale.data.maybe.Just
---

Constructs a Maybe value that represents a successful value (a `Just`).

> **NOTE**:
> The provided value is stored as-given in the structure. If you want to
> convert a nullable value (a value that may be null/undefined) to a Maybe
> value, use the `Maybe.fromNullable(value)` function instead of
> `Maybe.Just(value)`.
See the documentation for the Maybe structure to understand how to use this.


@annotate-multi: [folktale.data.maybe.Nothing.prototype.map, folktale.data.maybe.Just.prototype.map]
---

Transforms the value inside a Maybe structure with an unary function. Only
transforms values that are successful (`Just`), and constructs a new Maybe as a
result.

## Example::

const Maybe = require('folktale/data/maybe');

function increment(value) {
return value + 1;
}

Maybe.Just(1).map(increment);
// ==> Maybe.Just(2)

Maybe.Nothing().map(increment);
// ==> Maybe.Nothing()


@annotate-multi: [folktale.data.maybe.Nothing.prototype.apply, folktale.data.maybe.Just.prototype.apply]
---

Transforms a Maybe value using a function contained in another Maybe. As with
`.map()`, the Maybe values are expected to be `Just`, and no operation is
performed if any of them is a `Nothing`.


## Example::

const Maybe = require('folktale/data/maybe');

function increment(value) {
return value + 1;
}

Maybe.Just(increment).apply(Maybe.Just(1));
// ==> Maybe.Just(2)

Maybe.Just(increment).apply(Maybe.Nothing());
// ==> Maybe.Nothing()

Maybe.Nothing().apply(Maybe.Just(1));
// ==> Maybe.Nothing()


@annotate: folktale.data.maybe.of
---

Constructs a Maybe value that represents a successful value (a `Just`).

> **NOTE**:
> The provided value is stored as-given in the structure. If you want to
> convert a nullable value (a value that may be null/undefined) to a Maybe
> value, use the `Maybe.fromNullable(value)` function instead of
> `Maybe.of(value)`.
See the documentation for the Maybe structure to understand how to use this.


@annotate-multi: [folktale.data.maybe.Nothing.prototype.chain, folktale.data.maybe.Just.prototype.chain]
---

Transforms an entire Maybe structure with the provided function. As with
`.map()`, the transformation is only applied if the value is a `Just`, but
unlike `.map()` the transformation is expected to return a new `Maybe` value.

Having the transformation function return a new Maybe value means that the
transformation may fail, and the failure is appropriately propagated. In this
sense, `a.chain(f)` works similarly to the sequencing of statements done by the
`;` syntax in JavaScript — the next instruction only runs if the previous
instruction succeeds, and either instructions may fail.


## Example::

const Maybe = require('folktale/data/maybe');

function first(list) {
return list.length > 0 ? Maybe.Just(list[0])
: /* otherwise */ Maybe.Nothing();
}

first([]).chain(first);
// ==> Maybe.Nothing()

first([[1]]).chain(first);
// ==> Maybe.Just(1)

first([[]]).chain(first);
// ==> Maybe.Nothing()




96 changes: 76 additions & 20 deletions src/data/maybe/maybe.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,51 +12,120 @@

const assertType = require('folktale/helpers/assertType');
const assertFunction = require('folktale/helpers/assertFunction');
const { data, show, setoid} = require('folktale/core/adt');
const { data, show, setoid, serialize } = require('folktale/core/adt');
const provideAliases = require('folktale/helpers/provide-fantasy-land-aliases');


/*~
* ---
* category: Representing Failures
* authors:
* - "@boris-marinov"
* - Quildreen Motta
*/
const Maybe = data('folktale:Data.Maybe', {
Nothing() { },
Just(value) { return { value } }
}).derive(setoid, show);
/*~
* ---
* category: Constructing
* type: |
* forall a: () => Maybe a
*/
Nothing() {
},

/*~
* ---
* category: Constructing
* type: |
* forall a: (a) => Maybe a
*/
Just(value) {
return { value };
}
}).derive(setoid, show, serialize);

const { Nothing, Just } = Maybe;

const { Nothing, Just } = Maybe;
const assertMaybe = assertType(Maybe);


// -- Functor ----------------------------------------------------------
/*~
* ---
* category: Transforming Maybe values
* type: |
* forall a, b: (Maybe a).((a) => b) => Maybe b
*/
Nothing.prototype.map = function(transformation) {
assertFunction('Maybe.Nothing#map', transformation);
return this;
};

/*~
* ---
* category: Transforming Maybe values
* type: |
* forall a, b: (Maybe a).((a) => b) => Maybe b
*/
Just.prototype.map = function(transformation) {
assertFunction('Maybe.Nothing#map', transformation);
return Just(transformation(this.value));
};


// -- Apply ------------------------------------------------------------
/*~
* ---
* category: Transforming Maybe values
* type: |
* forall a, b: (Maybe (a) => b).(Maybe a) => Maybe b
*/
Nothing.prototype.apply = function(aMaybe) {
assertMaybe('Maybe.Nothing#apply', aMaybe);
return this;
};

/*~
* ---
* category: Transforming Maybe values
* type: |
* forall a, b: (Maybe (a) => b).(Maybe a) => Maybe b
*/
Just.prototype.apply = function(aMaybe) {
assertMaybe('Maybe.Just#apply', aMaybe);
return aMaybe.map(this.value);
};

// -- Applicative ------------------------------------------------------
Maybe.of = Just;
/*~
* ---
* category: Constructing
* type: |
* forall a: (a) => Maybe a
*/
Maybe.of = function(value) {
return Just(value);
};


// -- Chain ------------------------------------------------------------
/*~
* ---
* category: Transforming Maybes
* type: |
* forall a: (Maybe a).((a) => Maybe b) => Maybe b
*/
Nothing.prototype.chain = function(transformation) {
assertFunction('Maybe.Nothing#chain', transformation);
return this;
};

/*~
* ---
* category: Transforming Maybes
* type: |
* forall a: (Maybe a).((a) => Maybe b) => Maybe b
*/
Just.prototype.chain = function(transformation) {
assertFunction('Maybe.Just#chain', transformation);
return transformation(this.value);
Expand Down Expand Up @@ -104,19 +173,6 @@ Just.prototype.orElse = function() {


// -- Conversions -------------------------------------------------
Nothing.prototype.toJSON = function() {
return {
'#type': 'folktale:Maybe.Nothing'
};
};

Just.prototype.toJSON = function() {
return {
'#type': 'folktale:Maybe.Just',
value: this.value
};
};

Maybe.toEither = function(...args) {
return require('folktale/data/conversions/maybe-to-either')(this, ...args);
};
Expand All @@ -131,4 +187,4 @@ provideAliases(Just.prototype);
provideAliases(Nothing.prototype);
provideAliases(Maybe);

module.exports = Maybe;
module.exports = Maybe;

0 comments on commit 47a03dd

Please sign in to comment.