public static function shrink(callable $f, $roses) { $roses = FP::realize($roses); if (empty($roses)) { return self::pure(call_user_func($f)); } else { return new self(call_user_func_array($f, FP::realize(FP::map(FP::method('getRoot'), $roses))), FP::rgen(FP::map(FP::partial([__CLASS__, 'shrink'], $f), self::remove($roses)))); } }
function testPartition() { $this->assertEquals([[0], [1], [2]], FP::realize(FP::partition(1, FP::range(0, 3)))); $this->assertEquals([[0, 1], [2, 3], [4, 5], [6]], FP::realize(FP::partition(2, FP::range(0, 7)))); $this->assertEquals([[0, 1, 2], [3, 4, 5], [6, 7]], FP::realize(FP::partition(3, FP::range(0, 8)))); }
/** * creates a generator that produces values from specified generators based on * likelihoods. The likelihood of a generator being chosen is its likelihood divided * by the sum of all likelihoods. * * Example: * Gen::frequency( * 5, Gen::ints(), * 3, Gen::booleans(), * 2, Gen::alphaStrings() * ) * * @return Generator */ public static function frequency() { $args = func_get_args(); $argc = count($args); if ($argc < 2 || $argc % 2 != 0) { throw new \InvalidArgumentException(); } $total = array_sum(FP::realize(FP::takeNth(2, $args))); $pairs = FP::realize(FP::partition(2, $args)); return self::choose(1, $total)->bindGen(function (RoseTree $rose) use($pairs) { $n = $rose->getRoot(); foreach ($pairs as $pair) { list($chance, $gen) = $pair; if ($n <= $chance) { return $gen; } $n = $n - $chance; } }); }