Function composition

  • Pure functions and Curryization are easy to write onion code h of g of f of x.
    • ToUpper (.first(_.reverse(array)))
  • Function composition allows us to recombine fine-grained functions to generate a new function

Function composition let’s look at the pipeline

A -> fn(can also be multiple management – multiple functions) -> B

fn = compose(f1, f2, f3);
b = fn(a);
Copy the code

Function combination definition

  • Compose: If a function needs to be processed by multiple functions to get the final value, it is possible to combine the intermediate functions into a single function

    • A function is like a pipeline of data, and a combination of functions connects these pipes, allowing data to pass through multiple pipes to form the final result
    • Function combinations are executed from right to left by default
// combine functions
function compose (f, g) {
   return function (x) {
       return f(g(x))
   }
}
Copy the code

Combinatorial functions in Lodash

  • Lodash combines the flow() or flowRight() functions, both of which can combine multiple functions
  • Flow () runs from left to right
  • FlowRight () runs from right to left and is used more often
// Simulate flowRight in LoDash

const reverse = arr= > arr.reverse();
const first = arr= > arr[0];
const toUpper = s= > s.toUpperCase();

const f = compose(toUpper, first, reverse);
console.log(f(['one'.'two'.'three']))

function compose (. args) {
   return function (value) {
       return args.reverse().reduce(function (acc, fn){
           return fn(acc);
       }, value)    
   }
}

// es6
const compose = (. args) = > value= > args.reverse().reduce((acc, fn) = > fn(acc), value);


Copy the code

The combination of functions should satisfy the associativity law:

  • We can either combine g with H, or f with g, and it’s the same thing.
// Associativity
let f = compose(f, g, h);
let associative = compose(compose(f, g), h) == compose((f, compose(g, h));
Copy the code
Function combination debugging
 / / for
  // NEVER SAY DIE --> never-say-die
  const _ = require('lodash')
  
  // _.split()
  const split = _.curry((sep, str) = > _.split(str, sep))
  
  // _.toLower()
  const join = _.curry((sep, array) = > _.join(array, sep))
  
  const map = _.curry((fn, array) = > _.map(array, fn))
  const f = _.flowRight(join(The '-'), map(_.toLower), split(' '))
  
  console.log(f('NEVER SAY DIE'))
Copy the code

Lodash/fp modules

  • Lodash’s FP module provides a practical approach to functional programming friendly
  • Immutable auto-curried iteratee-first data-last method (function first, data after)
/ / lodash module
const _ = require('lodash')

_.map(['a'.'b'.'c'], _.toUpper)
// => ['A', 'B', 'C']
_.map(['a'.'b'.'c'])
// => ['a', 'b', 'c']

_.split('Hello World'.' ')


/ / lodash/fp module

const fp = require('lodash/fp')

fp.map(fp.toUpper, ['a'.'b'.'c'])
fp.map(fp.toUpper)(['a'.'b'.'c'])

fp.split(' '.'Hello World')
fp.split(' ') ('Hello World')


/ / for
/ NEVER SAY DIE  --> never-say-die
const fp = require('lodash/fp')

const f = fp.flowRight(fp.join(The '-'), fp.map(fp.toLower), fp.split(' '))
console.log(f('NEVER SAY DIE'))
Copy the code

The difference between loDash and the map method in the LoDash/FP module

const _ = require('lodash')
console.log(_.map(['23'.'8'.'10'.parseInt))
// => [23, NaN, 2]
/ / analysis
// Base 2-36 0 is not passed, default base 10
// 1. parseInt('23', 0, array)
// 2. parseInt('8', 1, array)
// 3. parseInt('10', 2, array)
Copy the code

Point Free

  • “Point Free”: We can define the process of data processing as a composite operation independent of data, without using the parameter representing data, as long as the simple operation steps are combined together. Before using this mode, we need to define some auxiliary basic operation functions.

    • There is no need to specify the data to be processed
    • You just need to synthesize the operation
    • You need to define some auxiliary basic operation functions
const f = fp.flowRight(fp.join(The '-'), fp.map(_.toLower), fp.split(' '))
Copy the code
Case presentation// Non-point Free mode
// Hello World => hello_world
function f (word) {
    return word.toLowerCase().replace(/\s+/g.'_')}// Point Free
const fp = require('lodash/fp')

const f = fp.flowRight(fp.replace(/\s+/g.'_'), fp.toLower)

console.log(f('Hello World'))


// Extract the first letter of a string and convert it to uppercase. Action separator
// world wild web ==> W. W. W

const fp = require('lodash/fp')

const firstLetterToUpper = fp.flowRight(fp.join('. ') ,fp.map(fp), fp.split(' '))

/ / improvement
const firstLetterToUpper = fp.flowRight(fp.join('. ') ,fp.map(fp.flowRight(fp.first, fp.toUpper)), fp.split(' '))

console.log(firstLetterToUpper('world wild web'))
Copy the code