docs: function morphic(options) {
    var optionsIn = options || {};
    var Matcher = optionsIn.matcherCore || defaultMatcher
    var matcher = new Matcher(optionsIn);
    var generateMatchers = optionsIn.generateMatchers || defaultGenerateMatchers;
    var generateNamedFieldExtractors = optionsIn.generateNamedFieldExtractors || defaultGenerateNamedFieldExtractors;
    var extractNamedFields = optionsIn.extractNamedFields || defaultExtractNamedFields;
  
    putRecord(matcher.useFallback.bind(matcher), [], function() {
      throw new Error("No methods matched input " + util.inspect(arguments));
    });
  
    var morphicFunction = function morphicFunction() {
      var match = matcher.getRecordFromInput(arguments);
      var extractedFields = extractNamedFields(match.namedFields || [], arguments);
      var args = [extractedFields].concat(Array.from(arguments));
      var action = match.action;
      return action.apply(this, args);
    };
  
    morphicFunction.with = function() {
      var generatedMatchers = generateMatchers(matchers, arguments);
      var namedFields = generateNamedFieldExtractors(generatedMatchers);
  
      return builder(
        putRecord.bind(
          undefined, matcher.addRecord.bind(matcher, generatedMatchers), namedFields));
    };
  
    morphicFunction.otherwise = function() {
      return builder(
        putRecord.bind(
          undefined, matcher.useFallback.bind(matcher), []));
    };
  
    return morphicFunction;
  }