functor-class
v1.0.0
Published
ES6 Library to define functors with classes
Downloads
6
Maintainers
Readme
functor-class
functor-class is a ES6 module to define functors (i.e. functions with attributes) with ES6 classes.
Usage
The functor.js package exposes the base class Functor
and other classical operators used in functional programming:
Mapper
Filter
Reducer
Composition
Functor
To define a custom functor as an ES6 class, the following construct can be used:
const {Functor} = require('functor-class');
class MyFunctor extends Functor {
constructor(attribute1, attribute2) {
// some type checking is allowed,
// but *this* should no be called before super
if (!attribute2) {
throw new Error('...');
}
super((arg1, arg2, arg3) => {
// arrow function are required here to be able to capture *this*
if (arg2 > this.attribute) {
// some code ...
return arg2 * arg3 + this.someGetter;
}
// To define a "read-only" attribute,
// simply use a closure without *this*
return arg1 + attribute1;
});
// functor parameters can be defined after
// super() and still be captured by closure
this.attribute = attribute2;
}
get someGetter() {
return this.attribute * 3;
}
someMethod() {
// do stuff ...
}
}
const myFunctorInstance = new MyFunctor(21, 55);
console.log(myFunctorInstance(1, 2, 3));
Mapper
To define a functor that maps a function onto an iterable object, use the Mapper
class:
const {Mapper} = require('functor-class');
const myMapper = new Mapper((x) => 2 * x - 1);
console.log(myMapper([1, 2, 3])); // == 1,3,5
Filter
To define a functor that filters an iterable object through a predicate, use the Filter
class:
const {Filter} = require('functor-class');
const myFilter = new Filter((x) => x >= 2);
console.log(myFilter([1, 2, 3])); // == 2,3
Reducer
To define a functor that reduces an iterable object through an operator, use the Reducer
class:
const {Reducer} = require('functor-class');
const myReducer = new Reducer((x, y) => x + y);
console.log(myReducer([1, 2, 3])); // == 6
Composition
To define a functor that applies a sequence of functions (or functors) on an object from left to right, use the Composition
class:
const {Composition} = require('functor-class');
const myComposition = new Composition(
(x) => x + 1,
(x) => [x, x * x],
(x, y) => x + y // the precedent result will be spread automatically
);
console.log(myComposition(2)); // == 12
Debug mode
An extra feature of the Functor
class and its subclasses is the ability to print out the steps of the computation in a logger
by passing {logger: someLoggingUtility, debug: true}
as a second argument options
. The default value of logger is console.log
.
For custom functors, this has to be done manually through the logger
attribute.
For the Mapper
, Filter
, Composition
, and Reducer
subclasses,
Library Functors
const {Filter} = require('functor-class');
const winston = require('winston');
const myFilter = new Filter(
(x) => x >= 2,
{logger: winston.debug, debug: true}
);
// will log the input, the number of elements before and after, and the output
myFilter([1, 2, 3]);
myFilter.logger = undefined;
// will default back to console.log;
myFilter([1, 2, 3]);
myFilter.debug = false;
// will not log anymore
myFilter([1, 2, 3]);
Note: the Composition
functor cannot accept the options argument within the constructor because it takes a spread array of functions, therefore, the logger and debug attribute can only be set after the instantiation.
Custom Functors
const {Functor} = require('functor-class');
class myFunctor extends Functor {
constructor(a, b, options) {
super((x) => {
// do stuff ...
this.logger(`log ${stuff} ...`);
return stuff;
},
options);
this.a = a;
this.b = b;
}
}
The myFunctor
instances will now have a logger
and debug
attribute options
argument and behave like other default functors.