function forall() {
  var args = Array.prototype.slice.call(arguments);
  var gens = args.slice(0, -1);
  var property = args[args.length - 1];
  var env;

  var lastgen = gens[gens.length - 1];

  if (!isArbitrary(lastgen) && typeof lastgen !== "string") {
    env = utils.merge(environment, lastgen);
    gens = gens.slice(0, -1);
  } else {
    env = environment;
  }

  assert(gens.length > 0, "forall requires at least single generator");

  // Map typify-dsl to hard generators
  gens = gens.map(function (g) {
    g = typeof g === "string" ? typify.parseTypify(env, g) : g;
    return utils.force(g);
  });

  assert(typeof property === "function", "property should be a function");

  function test(size, x, shrinks) {
    assert(Array.isArray(x), "generators results should be always tuple");

    return functor.bind(property, x, function (r, exc) {
      if (r === true) {
        return true;
      } else if (typeof r === "function") {
        var rRec = r(size);

        return functor.map(rRec, function (rRecPrime) {
          if (rRecPrime === true) {
            return true;
          } else {
            return shrinkResult(gens, x, test, size, shrinks, exc, function (rr) {
              return {
                counterexample: rr.counterexample.concat(rRecPrime.counterexample),
                counterexamplestr: rr.counterexamplestr, // + "; " + rRec.counterexamplestr,
                shrinks: rr.shrinks,
                exc: rr.exc || rRecPrime.exc,
              };
            });
          }
        });
      } else {
        return shrinkResult(gens, x, test, size, shrinks, exc || r, utils.identity);
      }
    });
  }

  return function (size) {
    var x = gens.map(function (arb) { return arb.generator(size); });
    var r = test(size, x, 0);
    return r;
  };
}
- `forall(arbs: arbitrary a ..., userenv: (map arbitrary)?, prop : a -> property): property`

      Property constructor