javascript es6 double arrow functions

This answer is for those who still have some doubts in double arrow functions. Lets dig deep into it.

const doubleArrowFunc = param1 => param2 => {
   console.log('param1', param1);
   console.log('param2', param2);
}

If you call this function

const executeFunc = doubleArrowFunc('Hello');

If you print executeFunc in console you'll get an output like this

ƒ (param2) {
    console.log('param1', param1);
    console.log('param2', param2);
  }

Now this is like a half executed code. If you wanna execute it fully, you've to do it like this

executeFunc('World');
//And the output will be 
param1 Hello
param2 World

If you want even more understanding. I can execute the same without arrow function

function doubleArrowFunc(param1) {
    return function innerFunction(param2) {
       console.log('param1', param1);
       console.log('param2', param2);
    }
}

The answer to your first question is more or less (see my comment). The answer to your second question is that the pattern you are seeing is a combination of using a closure and currying. The original parameters to the exported function get gathered into an array called 'middlewares' that the returned functions close over (i.e. have access to). The function then can be called again with yet another parameter 'createStore' then another function is returned that can accept even more parameters. This allows one to partially apply the parameters. For a more trivial (and perhaps more easily comprehended) example, lets take a function called 'add' that adds two numbers:

let add = (x, y) => x + y;

Not very interesting. But lets break it up so it can take the first number and return a function that takes the second:

let add = x => y => x + y;
let add3 = add(3);
let seven = add3(4); // 7

This may not seem like a big win for our add function, but you started with a much more reasonable real-world example. Additionally, rather than currying manually it is possible (and desirable) to use a curry function that does it for you, many popular libraries (lodash, underscore, ramda) implement curry for you. An example using Ramda:

let add = R.curry((x, y) => x + y);
let add3 = add(3);
let five = add3(2);
let also5 = add(3, 2);
let still5 = add(3)(2); // all are equivalent.