This small library provides implementations of NonEmptyList and NonEmptyArray: collection structures that guarantee you'll have at least one value. Additionally, you can build on top of the NonEmptyBase module to make a NonEmpty* version of your own collection type.
Install via npm:
npm install --save bs-nonempty
Update your bsconfig.json
"bs-dependencies": [
  "bs-nonempty"
],
The following demonstrates the API for using this library with List, but from these examples, it should be pretty easy to figure out how the NonEmptyArray version works.
Construct a NonEmptyList
For constructing a new NonEmptyList.t, you can use make, pure, cons, and fromT. You can turn your NonEmptyList.t into a list using toT. The signatures of those functions look like:
let make: ('a, list('a)) => NonEmptyList.t('a);let pure: ('a) => NonEmptyList.t('a);
let cons: ('a, NonEmptyList.t('a)) => NonEmptyList.t('a);let fromT: list('a) => option(NonEmptyList.t('a));
let toT: NonEmptyList.t('a) => list('a);You can use those functions like this:
/* "import" from NonEmptyList */
let (make, pure, cons, head, tail, fromT, toT) =
  NonEmptyList(make, pure, cons, head, tail, fromT, toT);
let myNel = pure(3);
head(myNel); /* 3 -- Note that this is not Some(3) */
tail(myNel); /* [] */
make(3, [2, 1]) == cons(3, cons(2, pure(1)));
toT(make(3, [2, 1])) == [3, 2, 1];
fromT(["A"]) == Some(make("A", [])) == Some(pure("A"));
fromT([]) == None;Map, fold (reduce), and more
let map: ('a => 'b, NonEmptyList.t('a)) => NonEmptyList.t('b);
let fold_left: (('a, 'b) => 'a, 'a, NonEmptyList.t('b)) => 'a;
let foldl1: (('a, 'a) => 'a, NonEmptyList.t('a)) => 'a;
let myNel = make(0, [1, 2, 3, 4]);
map(string_of_int, myNel); /* == make("0", ["1", "2", "3", "4"]) */
fold_left((+), 0, myNel); /* 10 */
foldl1((+), myNel); /* 10 */let append: (NonEmptyList.t('a), NonEmptyList.t('a)) => NonEmptyList.t('a);
let join: (NonEmptyList.t(NonEmptyList.t('a))) => NonEmptyList.t('a);
let reverse: NonEmptyList.t('a) => NonEmptyList.t('a);
let length: NonEmptyList.t('a) => int;Note: If "semigroup" is a word that freaks you out, you can ignore this entire section. You already know more than enough to use this library. But if you're already familiar with bs-abstract, the following might come in handy.
NonEmpty is built on top of the great work in bs-abstract. Every NonEmpty* implementation (currently List and Array) is a member of the following typeclasses (which can be accessed like NonEmptyList.Functor.map):
- MAGMA_ANY and SEMIGROUP_ANY with infix append(e.g.NonEmptyList.Infix.(<:>))
- FUNCTOR with infix map(e.g.NonEmptyList.Infix.(<$>))
- APPLY and APPLICATIVE with infix apply(e.g.NonEmptyList.Infix.(<*>))
- MONAD with infix flat_map(e.g.NonEmptyList.Infix.(>>=))
Additionally, to roll your own NonEmpty* type, the underlying container type needs to be a member of MONOID_ANY, APPLICATIVE, and FOLDABLE (as well as provide implementations for head, tail, and length functions). See the implementations of NonEmptyList and NonEmptyArray for examples.
- Fork and clone this repository
- npm installto grab- bs-abstractand any dev dependencies
- Add features (and tests!) as appropriate
- npm run test
Here are some things worth contributing:
- fold_rightimplementation so we can be a member of- FOLDABLE
- EQif the underlying- 'ais a member of- EQ
- TRAVERSABLEif the underlying- 'ais a member of- APPLICATIVE
- docblock comments so we can automate the documentation
- Any extra utility functions or NonEmptyOtherCollectionTypeimplementations
Released under the MIT license. See LICENSE.