generate = (mShape, fill) => {
  /**
   * Generates the matrix recursively.
   *
   * @param {Shape} recShape - the shape of the matrix to generate
   * @param {CellIndices} recIndices
   * @returns {Matrix}
   */
  const generateRecursively = (recShape, recIndices) => {
    if (recShape.length === 1) {
      return Array(recShape[0])
        .fill(null)
        .map((cellValue, cellIndex) => fill([...recIndices, cellIndex]));
    }
    const m = [];
    for (let i = 0; i < recShape[0]; i += 1) {
      m.push(generateRecursively(recShape.slice(1), [...recIndices, i]));
    }
    return m;
  };

  return generateRecursively(mShape, []);
}
Generates the matrix of specific shape with specific values.

@param {Shape} mShape - the shape of the matrix to generate
@param {function({CellIndex}): Cell} fill - cell values of a generated matrix.
@returns {Matrix}