Сергей Ткаченко, ЯндексМаркет
Сергей Ткаченко,
Разработчик интерфейсов
Что такое ФП?
Это набор идей, а не чёткие инструкции и действия
var calculateTotalPrice = data => {
// ...
};
fs.readFile('./offers.csv', 'utf8', calculateTotalPrice);
var someGlobalFlag = true;
var swapState = data => {
if (data.needSwapState) {
someGlobalFlag = !someGlobalFlag;
}
};
var someGlobalFlag = true;
var swapState = (data, flag) => {
if (data.needSwapState) {
return flag ? true : false;
}
};
var newGlobalFlag = swapState(data, someGlobalFlag);
var toUpperCaseAll = (list) => {
for (let i = 0; i < list.length; i++) {
list[i] = list[i].toUpperCase();
}
return list;
};
toUpperCaseAll(['mike', 'leo', 'raf', 'don']);
// ['MIKE', 'LEO', 'RAF', 'DON']
var toUpperCaseAll = (list) => {
var result = [];
for (let i = 0; i < list.length; i++) {
result[i] = list[i].toUpperCase();
}
return result;
};
toUpperCaseAll(['mike', 'leo', 'raf', 'don']);
// ['MIKE', 'LEO', 'RAF', 'DON']
var add = (a, b) => a + b;
add(2, 5) // 5
add(2, 5) // 5
add(2, 5) // 5
Чистые функции
a + b
var add = (a, b) => a + b;
add(2, 5);
var five = 5;
var five = () => 5;
var transformList = (callback, list) => {
var result = [];
for (let value of list) {
let newValue = callback(value);
result.push(newValue);
}
return result;
}
function transformList(callback, [x, list]) {
if (!x) return [];
return [callback(x), . . . transformList(callback, list)];
}
var add = function (x) {
return function (y) {
return x + y;
};
};
var increment = add(1);
var addTen = add(10);
var add3 = (a, b, c) => a + b + c;
var add3Curryed = curry(add3);
add3Curryed(1, 2, 3); // 6
add3Curryed(1)(2, 3); // 6
add3Curryed(1, 2)(3); // 6
add3Curryed(1)(2)(3); // 6
curry = func => {
var arity = func.length;
return function f1(. . . args) {
if (args.length >= arity) {
return func.apply(null, args);
} else{
return function f2(. . . nargs) {
return f1.apply(null, args.concat(nargs));
};
}
};
};
var capitalize = str => str.charAt(0).toUpperCase() + str.slice(1);
var trim = str => str.trim();
var formatStr = compose(capitalize, trim);
var split = curry((separator, str) => str.split(separator));
var join = curry((separator, list) => list.join(separator));
var map = curry((func, list) => list.map(func));
var toLowerCase = str => str.toLowerCase();
var toSlug = compose(
encodeURIComponent,
joinString('-'),
map(stringToLowerCase),
splitString(' ')
);
var compose = (. . . funcs) =>
(value) => funcs.reverse().reduce((v,fn) => fn(v), value);
var getRows = pluck('rows');
var getNames = pluck('name');
var renderUsersTable = Engine.render('users-table');
var getUsersFromDb = compose(getRows, User.findAll);
var cleanUpData = compose(capitalise, getNames);
var makePage = compose(renderUsersTable, map(cleanUpData), getUsersFromDb);
makePage( {limit: 20} );
var Container = function(x) {
this.__value = x;
};
Container.of = x => new Container(x);
Container.prototype.map = func => {
return Container.of(func(this.__value));
};
Container.of(2).map(function(two){ return two + 2 });
// Container(4)
var getUsersFromDb = compose(getRows, User.findAll);
var getUsersFromDb = compose(getRows, Maybe.of, User.findAll);
var getUsersFromDb = compose(map(getRows), Maybe.of, User.findAll);
getUsersFromDb() // Maybe([{name: 'leo', name: 'don']);
getUsersFromDb() // Maybe(null);
var Maybe = function(x) {
this.__value = x;
}
Maybe.of = function(x) {
return new Maybe(x);
}
Maybe.prototype.isNothing = function() {
return (this.__value === null || this.__value === undefined);
}
Maybe.prototype.map = function(f) {
return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this.__value));
}
var renderUsersTable = Engine.render('users-table');
var makePage = compose(
map(renderUsersTable),
map(cleanUpData),
getUsersFromDb
);
var errorMessage = 'sorry there is no users';
var errorContainer = Either.Left(errorMessage);
var getUsers = cond([
[isArrayLike, Either.Right],
[T, always(errorContainer)]
]);
var getUsersFromDb = compose(map(getRows), getUsers, User.findAll);
var renderUsersTable = Engine.render('users-table');
var renderErrorMessage = Engine.render('error-message');
var render = Either.either(renderErrorMessage, renderUsersTable);
var makePage = compose(render, getUsersFromDb);
var getUsersFromDb = compose(getRows, User.findAll);
var findAll = params =>
Future((reject, resolve) =>
User.findAll(params)
.then(resolve)
.catch(reject));
var getUsersFromDb = compose(map(getRows), findAll);
var makePage = compose(map(cleanUpData), getUsersFromDb);
var page = makePage({limit: 20});
page.fork(renderErrorMessage, renderUsersTable);
var getRows = pluck('rows');
var getNames = pluck('name');
var cleanUpData = compose(capitalise, getNames);
var renderUsersTable = Engine.render('users-table');
var renderErrorMessage = Engine.render('error-message');
var render = Either.either(renderErrorMessage, renderUsersTable);
var render = . . .
var errorMessage = 'sorry there is no users';
var errorContainer = Either.Left(errorMessage);
var getUsers = cond([
[isArrayLike, Either.Right],
[T, always(errorContainer)]
]);
var findAll = params =>
Future((reject, resolve) =>
User.findAll(params).then(resolve).catch(reject));
var getUsersFromDb = compose(flatMap(getRows), map(getUsers), findAll);
var render = . . .
var getUsersFromDb = . . .
var makePage = compose(map(render), flatMap(cleanUpData), getUsersFromDb);
var page = makePage({limit: 20});
page.fork(logError, insertToDOM);
Homer Simpson. ©1999 20TH CENTURY FOX FILM CORP.
Сергей Ткаченко
Разработчик интерфейсов
ts1503@yandex-team.ru
@tka4enko1503