Hardcore functional programming
-
Upload
leonardo-crespo -
Category
Technology
-
view
369 -
download
2
description
Transcript of Hardcore functional programming
Hardcore functional programming
in JavascriptLeonardo Garcia Crespo@leogcrespogh/leoasis
Agenda
● Currying & Partial Application● Function Composition● Fantasy Land● Functors● Monads
Currying
Currying:
f(x, y, z) = r
f(x) -> g(y) -> h(z) => r
function add(a) {
return function(b) {
return a + b;
};
}
var add1 = add(1);
add1(3); // 4
function makeFullName(first) {
return function(middle) {
return function(last) {
return first + ' ' + middle + ' ' + last;
};
};
}
var makeJerry = makeFullName('Jerry');
makeJerry('Lee')('Lewis');
var add1 = add(1);
add1(2); // 3
add(1)(2); // 3
add(1, 2); // ?
_.curry(fn)
var add = _.curry(function(a, b) {
return a + b;
});
var add1 = add(1);
add1(2); // 3
add(1)(2); // 3
add(1, 2); // 3
Partial Application
var add1 = add(1);
var add1 = add.bind(null, 1);
var add1 = _.partial(add, 1);
Function Composition
(f . g)(x) = f(g(x))
_.compose(f, g)(x) == f(g(x))
_.compose(reverse, toUpper)
_.compose(reverse, toUpper)
"Hello"
_.compose(reverse, toUpper)
"Hello"
_.compose(reverse, toUpper)
"HELLO"
_.compose(reverse, toUpper)
"HELLO"
_.compose(reverse, toUpper)
"HELLO"
_.compose(reverse, toUpper)
"OLLEH"
_.compose(reverse, toUpper)
"OLLEH"
_.compose(reverse, toUpper)
"OLLEH"
Problem with _
Data comes first:
_.map(list, fn)
_.reduce(list, fn)
_.pluck(list, prop)
...
If data came last:
var add1ToAll = _.map(add1);
var names = _.map(get('name'));
Examples
Fantasy Land
Functor
Semigroup
Monoid
Apply
Chain
Applicative
Monad
Map for lists:
map :: (a -> b) -> [a] -> [b]
map(add1, [1, 2, 3]) // [2, 3, 4]
Functors
map :: (a -> b) -> F a -> F b
where F is a functor
Laws
Identity:
map(id, F a) == F a
map(id) == id
Composition:
map(f . g) == map(f) . map(g)
Maybe Functor
map(add1, Maybe(2)); // Maybe(3)
map(add1, Maybe(null)); // Maybe(null)
Promise Functor
map(add1, Promise(2)); // Promise(3)
map(add1, delay(3)); // Promise(...4)
Examples
Monads
A functor that also has:
of :: a -> M a
flatMap :: (a -> M b) -> M a -> M b
or chain :: M a -> (a -> M b) -> M b
Laws
Left Identity:
of(a).chain(f) == f(a)
Right Identity:
M(a).chain(of) == M(a)
Associativity:M(a).chain(f).chain(g) == M(a).chain(x -> f(x).chain(g))
List Monad
Array.of(1); // [1]
var withNeg = function(a) { return [-a, a]; };
flatMap(withNeg, [1, 2, 3]); // [-1, 1, -2, 2, -3, 3]
[1, 2, 3].chain(withNeg);
Maybe Monad
Maybe.of(1); // Maybe(1)
var getName = function(obj) { return Maybe(obj.name); };
flatMap(getName, Maybe({name: 'John'})) // Maybe('John')
Maybe({name: 'John'}).chain(getName);
flatMap(getName, Maybe({age: 20})); // Maybe(null)
Promise Monad
Promise.of(1); // Promise(1)
// findTodo :: Number -> Promise(todo)
var findTodo = function(id) {
return fetchFromDb('todo', id);
};
flatMap(findTodo, Promise.of(123)); // Promise(...todo)
Promise.of(123).chain(getName);
Examples
Next
● Monoids● Applicative Functors● Learn a FP language!● A LOT more than this
Why?
● Declarative (what vs how)● Common Patterns● Small functions● Oriented to fns, not data● Correctness (mathematics)
Resources
● http://learnyouahaskell.com/● Hey Underscore! You're Doing it wrong (https:
//www.youtube.com/watch?v=m3svKOdZijA)● https://github.com/fantasyland/fantasy-land● http://functionaltalks.org● Brian McKenna (@puffnfresh) & Brian Lonsdorf
(@drboolean) on Twitter
Thanks!
Qs?
Leonardo Garcia Crespo@leogcrespogh/leoasis