# fl

> Functional lazy sequence operators

Latest version **0.1.1** (published 2014-07-12) · 0 weekly downloads

## Install

```sh
npm install fl
pnpm add fl
yarn add fl
bun add fl
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.1 |
| Published | 2014-07-12 |
| First published | 2014-05-03 |
| Weekly downloads | 0 |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Nick Fargo |
| Maintainers | nickfargo |
| Keywords | functional, lazy, sequence, collections |

## Links

- npm: https://www.npmjs.com/package/fl
- Repository: https://github.com/nickfargo/fl
- Issues: https://github.com/nickfargo/fl/issues
- npm.io page: https://npm.io/package/fl

## Recent versions

- 0.1.1 (latest) — 2014-07-12
- 0.1.0 — 2014-05-03

## README

# fl.js

Functional lazy operators and sequences.

* Uses standard [Iterator][] protocol
* Accepts ES6 generators as lazy sequences
* Designed to collaborate with modules such as **[pim.js][]**, which provides persistent immutable data structures



## API



### General value operators


#### identity

```js
identity( value )
```

Returns `value`.


#### increment

```js
increment( value )
```

Returns `value + 1`.


#### decrement

```js
decrement( value )
```

Returns `value - 1`.


#### isEven

```js
isEven( value )
```

Returns `value % 2 === 0`.


#### isOdd

```js
isOdd( value )
```

Returns `value % 2 === 1 || value % 2 === -1`.


#### sum

```js
sum( ...addends )
```

Returns the sum of `0` and zero or more `addends`.


#### multiply

```js
multiply( ...factors )
```

Returns the product of `1` and zero or more `factors`.


#### toArray

```js
Sequence().toArray()
// >>> array

toArray( sequence )
// >>> array
```

Iterates through a sequence and returns its elements in an array.


#### complement

```js
complement( predicate )
```

Returns a function that returns the logical negation of the result of applying `predicate`.

```js
complement( isEven )(3);
true
```


#### compose

```js
compose( ...fns )
```

Returns the composition of a series of functions `fns`, such that `compose(f,g,h)(x)` is equivalent to `f(g(h(x)))`.


#### partial

```js
partial( fn, ...args )
```

Given a function `fn` and successive arguments `args` fewer in number than the expected number of parameters for `fn`, returns a function that will return the result of applying `fn` to the concatentation of `args` and its own arguments.

```js
addFive = partial( sum, 5 );
addFive(2);
7

rest = partial( dropWhile, function ( value, index ) {
  return index < 1;
});
// >>> function

toArray( rest( range(4) ) );
[ 1, 2, 3 ]

toArray( rest( function* () {
  yield 2; yield 4; yield 6; yield 8;
}));
[ 4, 6, 8 ]
```


#### apply

```js
apply( fn, sequence )
```

Returns the result of applying `fn` with each element in `sequence` as arguments.


#### compare

The default comparator function used with `sort`. Determines the ordinal relation between arguments `x` and `y`.

```js
compare( x, y )
// >>> number
```

Returns `0` if `x` and `y` are of equal precedence, returns `-1` if `x` precedes `y`, or returns `1` if `y` precedes `x`. If `x` and `y` are logical sequences, then the comparison is evaluated recursively over the respective elements of both sequences.


#### comparator

Creates a boolean valued comparison operator.

```js
comparator( predicate )
// >>> function
```

Returns a predicate that returns `true` if applying `predicate` to each adjacent pairing of its arguments also returns `true`, and returns `false` otherwise.

```js
nonconsecutive = comparator( compare );

apply( nonconsecutive, 'fireman' );  // >>> true
apply( nonconsecutive, 'balance' );  // >>> true
apply( nonconsecutive, 'ladders' );  // >>> false
```


#### increasing

```js
increasing( ...values )
// >>> boolean
```

Returns `true` if arguments are provided in a strictly increasing order (`<`) as determined by `compare`; otherwise returns `false`.

Logically equivalent to `comparator( (x,y) => compare(x,y) < 0 )`.

```js
apply( increasing, [0,1,4,9] );  // >>> true
apply( increasing, [1,1,2,3] );  // >>> false
apply( increasing, 'gist' );     // >>> true
apply( increasing, 'bees' );     // >>> false

apply( increasing, Sequence.range().take(5) );
// >>> true
```


#### decreasing

```js
decreasing( ...values )
// >>> boolean
```

Returns `true` if arguments are provided in a strictly decreasing order (`>`) as determined by `compare`; otherwise returns `false`.

```js
apply( decreasing, [9,4,1,0] );  // >>> true
apply( decreasing, [3,2,1,1] );  // >>> false
apply( decreasing, 'wronged' );  // >>> true
apply( decreasing, 'sniffed' );  // >>> false
```


#### nonincreasing

```js
nonincreasing( ...values )
// >>> boolean
```

Returns `true` if arguments are provided in a monotonically decreasing order (`>=`) as determined by `compare`; otherwise returns `false`.

```js
apply( nonincreasing, 'sniffed' );  // >>> true
```


#### nondecreasing

```js
nondecreasing( ...values )
// >>> boolean
```

Returns `true` if arguments are provided in a monotonically increasing order (`<=`) as determined by `compare`; otherwise returns `false`.

```js
apply( nondecreasing, 'bees' );  // >>> true
```



### Sequential functions


#### first

```js
Sequence().first()
// >>> *

first( sequence )
// >>> *
```

Returns the first element in `sequence`.

```js
first( range(4) );
0

first([]);
undefined
```

Logically equivalent to `take( 1, sequence )().next().value`.


#### rest

```js
Sequence().rest()
// >>> Sequence

rest( sequence )
// >>> function
```

Returns a logical sequence of the elements that follow the `first` element of `sequence`.

```js
toArray( rest([ 0, 1, 2, 3 ]) );
[ 1, 2, 3 ]

toArray( rest([ 1 ]) );
[]

toArray( rest( [] ) );
[]

Sequence.range( 3, Infinity ).rest().take(4).toArray();
[ 4, 5, 6, 7 ]
```

Logically equivalent to `drop( 1, sequence )`.


#### range

Defines a sequence of numbers from `start` up to but excluding `end` in increments of `step`.

```js
Sequence.range()
Sequence.range( end )
Sequence.range( start, end )
Sequence.range( start, end, step )
// >>> Sequence

range()
range( end )
range( start, end )
range( start, end, step )
// >>> function
```

Defaults for arguments not provided are: `start = 0`, `end = Infinity`, `step = 1`.

Returns a `Sequence` or sequence generator function.

```js
toArray( range(4) );
[ 0, 1, 2, 3 ]

toArray( take( 5, range() ) );
[ 0, 1, 2, 3, 4 ]

toArray( range(-5) );
[]

toArray( range(3,9,2) );
[ 3, 5, 7 ]
```


#### iterate

Given a nominally pure function `f` and *seed* value `x`, defines an infinite sequence of `x`, `f(x)`, `f(f(x))`, etc.

```js
Sequence.iterate( fn, seed )
// >>> Sequence

iterate( fn, seed )
// >>> function
```

Returns a `Sequence` or sequence generator function.

```js
toArray( take( 5, iterate( increment, 42 ) ) );
[ 42, 43, 44, 45, 46 ]
```


#### repeat

Given a value `x`, defines a repeating infinite sequence of `x`, or a finite sequence of `x` repeated up to `limit` times.

```js
Sequence.repeat( value )
Sequence.repeat( value, limit )
// >>> Sequence

repeat( value )
repeat( value, limit )
// >>> function
```

Returns a `Sequence` or sequence generator function.

```js
toArray( take( 5, repeat(42) ) );
[ 42, 42, 42, 42, 42 ]

Sequence.repeat( 'foo', 5 );
[ 'foo', 'foo', 'foo', 'foo', 'foo' ]
```


#### cycle

Defines an infinite sequence that repeats the items in `sequence` indefinitely.

```js
Sequence.cycle()
// >>> Sequence

cycle( sequence )
// >>> function
```

Returns a `Sequence` or sequence generator function.

```js
toArray( take( 10, cycle([3,4,5,6]) ) );
[ 3, 4, 5, 6, 3, 4, 5, 6, 3, 4 ]

Sequence([3,4,5,6]).take(10).toArray();
[ 3, 4, 5, 6, 3, 4, 5, 6, 3, 4 ]
```


#### filter

Applies a nominally pure `predicate` to each item in `sequence` and keeps those items for which `predicate` returns logical true.

```js
Sequence().filter( predicate )
// >>> Sequence

filter( predicate, sequence )
// >>> function
```

Returns a `Sequence`, or sequence generator function, consisting of each element `x` in `this` or `sequence` for which the expression `!!predicate(x)` would equal `true`.

```js
Sequence(["all", "your", "base", "are", "belong"]).filter( function (word) {
  return word.length < 4;
});
[ 'all', 'are' ]
```


#### remove

Performs a `filter` on the `complement` of the provided `predicate`.


#### map

Applies `fn` to successive items of one or more sequences.

```js
Sequence().map( fn, ...sequences )
// >>> Sequence

map( fn, sequence, ...sequences )
// >>> function
```

The arity of `fn` should correspond with the number of sequences to be mapped.

Returns a `Sequence`, or sequence generator function, consisting of the result of applying `fn` to successive items taken from `sequence` and any additional `sequences`, in parallel, until any of `sequence` or `sequences` is exhausted.

```js
toArray( map( increment, [1,2,3] ) );
[ 2, 3, 4 ]

Sequence([1,2,3]).map( increment ).toArray();
[ 2, 3, 4 ]

toArray( map( sum, [1,2,3], [10,20,30] ) );
[ 11, 22, 33 ]

Sequence([1,2,3]).map( sum, [10,20,30], [100,200,300] ).toArray();
[ 111, 222, 333 ]

Sequence([1,2,3]).map( sum, [10,20] ).toArray();
[ 11, 22 ]

Sequence( iterate increment, 1 ).map( sum, range(10,50,10) ).toArray();
[ 11, 22, 33, 44 ]
```


#### reduce

Iteratively calls `fn`, with two arguments:

  1. `seed` on the first iteration; thereafter, the result of the previous iteration

  2. each successive value in `sequence`.

If no `seed` is provided, the first value of the sequence is used as the `seed` and reduction proceeds on the remainder of the sequence.

```js
Sequence().reduce( fn, seed )
Sequence().reduce( fn )
// >>> *

reduce( fn, seed, sequence )
reduce( fn, sequence )
// >>> *
```

Returns the result of the final iteration of `fn`. If the length of `sequence` is zero, returns the result of calling `fn` with no arguments. If the length of `sequence` is `1`, the single element of `sequence` is returned.

```js
function factorial (n) {
  return Sequence.range(n).map( increment ).reduce( multiply );
}
```


#### reductions

Produces a sequence of the intermediate values in a `reduce` operation.

```js
Sequence().reductions( fn, seed )
Sequence().reductions( fn )
// >>> Sequence

reductions( fn, seed, sequence )
reductions( fn, sequence )
// >>> function
```

Returns a `Sequence`, or sequence generator function, of reductions.

```js
Sequence.range(1,10).reductions( multiply ).toArray();
[ 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 ]

function factorialSequence (n) {
  return Sequence.range(n).map( increment ).reductions( multiply );
}
factorialSequence(10).toArray();
[ 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 ]
```


#### take

Defines a sequence of up to `amount` items taken successively from `sequence`, or

```js
Sequence().take( amount )
// >>> Sequence

take( amount, sequence )
// >>> function
```

Returns a `Sequence` or sequence generator function.


#### takeWhile

Defines a sequence of items taken successively from `sequence` so long as the expression `!!predicate( item )` remains equal to `true`.

```js
Sequence().takeWhile( predicate )
// >>> Sequence

takeWhile( predicate, sequence )
// >>> function
```

Returns a `Sequence` or sequence generator function.

```js
Sequence
  .range()
  .takeWhile( function (x) {
    return Math.log(x) < 1;
  })
  .toArray();
[ 0, 1, 2 ]
```


#### drop

```js
Sequence().drop( amount )
// >>> Sequence

drop( amount, sequence )
// >>> function
```

Returns a sequence of the items in `sequence` that would be excluded from the subsequence returned by an equivalent `take` operation.


#### dropWhile

```js
Sequence().dropWhile( predicate )
// >>> Sequence

dropWhile( predicate, sequence )
// >>> function
```

Returns a sequence of the items in `sequence` that would be excluded from the subsequences returned by an equivalent `takeWhile` operation.


#### concat

Concatenates sequences.

```js
Sequence().concat( ...sequences )
// >>> Sequence

concat( sequence, ...sequences )
// >>> function
```

Returns a single `Sequence`, or a sequence generator function, that is the concatentation of each sequence in the order they are provided.

```js
Sequence.range(3).concat( range(5) ).toArray();
[ 0, 1, 2, 0, 1, 2, 3, 4 ]

Sequence('abc').concat('def', 'ghi').toArray();
[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' ]

toArray( concat() );
[]
```


#### splitAt

Divides a `sequence` into two sequences, where the first contains the first `n` elements of `sequence`, and the second contains the remaining elements of `sequence`.

```js
Sequence().splitAt( n )
// >>> array

splitAt( n, sequence )
// >>> array
```

Returns a two-element array containing both partitions of `sequence`.

```js
Sequence('qwerty')
  .splitAt(4)
  .map( Sequence )
  .map( function (s) {
    return s.toArray().join('');
  });
[ 'quer', 'ty' ]
```


#### splitWith

Divides a `sequence` into two sequences, where the first contains elements, starting from the head of `sequence`, that return logical true when `predicate` is applied to the element.

```js
Sequence().splitWith( predicate )
// >>> array

splitWith( predicate, sequence )
// >>> array
```

Returns a two-element array containing both partitions of `sequence`.

```js
function isConsonant (char) {
  return /[^aeiouy]/i.test(char);
}
Sequence('schtick')
  .splitWith( isConsonant )
  .map( Sequence )
  .map( function (s) {
    return s.toArray().join('');
  });
[ 'scht', 'ick' ]
```


#### partition

Partitions `sequence` into subsequences of `size` elements at offsets `stride` elements apart, where `stride` defaults to `size` such that partitions do not overlap. If the final partition is shorter than `size`, then: if a `padding` sequence is provided, that partition is filled with elements from `padding` until it grows to `size`; if no `padding` exists, the short partition is dropped.

```js
Sequence().partition( size, stride, padding )
Sequence().partition( size, stride )
Sequence().partition( size )
// >>> Sequence

partition( size, stride, padding, sequence )
partition( size, stride, sequence )
partition( size, sequence )
// >>> function
```

Returns a `Sequence` of partitions, or a sequence generator function that returns an iterator over the partitions, where each partition is itself a sequence generator function that returns an iterator over the elements of the partition.

```js
Sequence.range(12).partition(4).map( toArray ).toArray();
[ [ 0, 1, 2, 3 ], [ 4, 5, 6, 7 ], [ 8, 9, 10, 11 ] ]

Sequence.range(11).partition(4).map( toArray ).toArray();
[ [ 0, 1, 2, 3 ], [ 4, 5, 6, 7 ] ]

Sequence.range(16).partition(4,6).map( toArray ).toArray();
[ [ 0, 1, 2, 3 ], [ 6, 7, 8, 9 ], [ 12, 13, 14, 15 ] ]

Sequence.range(14).partition(4, 6, ['a']).map( toArray ).toArray();
[ [ 0, 1, 2, 3 ], [ 6, 7, 8, 9 ], [ 12, 13, 'a' ] ]

Sequence.range(14).partition(4, 6, 'abc').map( toArray ).toArray();
[ [ 0, 1, 2, 3 ], [ 6, 7, 8, 9 ], [ 12, 13, 'a', 'b' ] ]

Sequence.range(4).partition(10).map( toArray ).toArray();
[]

Sequence.range(4).partition(10,10,[]).map( toArray ).toArray();
[ [ 0, 1, 2, 3 ] ]
```


#### partitionBy

Applies `fn` to each value in `sequence`, partitioning it into subsequences each time `fn` returns a new value.

```js
Sequence().partitionBy( fn )
// >>> Sequence

partitionBy( fn, sequence )
// >>> function
```

Returns a `Sequence` of partitions, or a sequence generator function that returns an iterator over the partitions, where each partition is itself a sequence generator function that returns an iterator over the elements of the partition.

```js
Sequence
  .range(1,6)
  .partitionBy( function (x) { return x === 3 } )
  .map( toArray )
  .toArray();
[ [ 1, 2 ], [ 3 ], [ 4, 5 ] ]


Sequence( [1,1,1,2,2,3,3] ).partitionBy( isOdd ).map( toArray ).toArray();
[ [ 1, 1, 1 ], [ 2, 2 ], [ 3, 3 ] ]

Sequence( [1,1,1,2,2,3,3] ).partitionBy( isEven ).map( toArray ).toArray();
[ [ 1, 1, 1 ], [ 2, 2 ], [ 3, 3 ] ]


Sequence("Leeeeeerrrrooyyy")
  .partitionBy( identity )
  .map( toArray )
  .toArray();
[ [ 'L' ],
  [ 'e', 'e', 'e', 'e', 'e', 'e' ],
  [ 'r', 'r', 'r', 'r' ],
  [ 'o', 'o' ],
  [ 'y', 'y', 'y' ] ]
```


#### interleave

```js
Sequence.interleave( ...sequences )
Sequence().interleave( ...sequences )
// >>> Sequence

interleave( ...sequences )
// >>> function
```

Given one or more `sequences`, defines a sequence consisting of the first item from each of the `sequences`, continuing with the second item from each of the `sequences`, etc., stopping after any one of the `sequences` has been exhausted.

```js
Sequence.interleave( range(), [7,8,9] ).toArray();
[ 0, 7, 1, 8, 2, 9 ]  // no `3`
```


#### interpose

Places a `value` between each element in a `sequence`.

```js
Sequence().interpose( value )
// >>> Sequence

interpose( value, sequence )
// >>> function
```

Returns a new logical sequence containing the `value` interposed within the elements of the original sequence.

```js
Sequence("dmtr").interpose('e').toArray();
[ 'd', 'e', 'm', 'e', 't', 'e', 'r' ]
```


#### sort

Sorts the contents of a finite, homogeneous logical sequence, as directed by a pure function `comparator` if provided, or by `compare` otherwise. Elements of the sequence which are themselves sequences are compared by recursively comparing the respective elements of both nested sequences.

```js
Sequence().sort( comparator )
Sequence().sort()
// >>> Sequence

sort( comparator, sequence )
sort( sequence )
// >>> function
```

Returns a new logical sequence containing the sorted elements of the original sequence.

```js
Sequence([ 'abduct', 'abacus', 'abated', 'abate' ])
  .map( Sequence )
  .sort( compare )
  .map( toArray )
  .map( function (a) { return a.join(''); } )
  .toArray();
[ 'abacus', 'abate', 'abated', 'abduct' ]
```




* * *

### &#x1f44b;




[Iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol
[pim.js]: http://npmjs.org/package/pim

---
_Source: https://npm.io/package/fl · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
