PHP code example of krak / fn
1. Go to this page and download the library: Download krak/fn library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
krak / fn example snippets
use function Krak\Fun\Curried\{filter, map, op};
use function Krak\Fun\{compose};
use const Krak\Fun\Consts\{toArray};
$res = compose(
toArray,
map(op('*')(3)),
filter(op('>')(2))
)([1,2,3,4]);
assert($res == [9, 12]);
use Krak\Fun\{f, c};
$res = f\compose(
c\toArray,
c\map(c\op('*')(3)),
c\filter(c\op('>')(2))
)([1,2,3,4]);
assert($res == [9, 12]);
use Krak\Fun\{f, c};
$res = f\compose(
c\toArray,
c\map(function($tup) {
return $tup[0] + $tup[1];
}),
c\toPairs
)([1,2,3]);
// $res == [1, 3, 5]
use Krak\Fun\{f, c};
function getArrayRange(callable $toArray): array {
$toArray(f\range(1,3));
}
getArrayRange(c\toArray);
use Krak\Fun\{f, c};
$res = f\compose(
c\toArray,
map(partial(c\op, '*', 3))
)([1,2,3]);
assert($res == [3,6,9]);
func()
func($arg1)
func($oarg = null, $oarg1 = null)
func($arg1, $arg2)
func($arg1, $oarg = null)
f\compose(
function() {}, // do something else
c\dd(), // debug result here
function() {}, // do another thing that returns a single value
function() {} // do something
);
f\compose(
function() {}, // do something else
c\dd(), c\toArray, // debug result here
c\map(function() {}) // do something
);
use Krak\Fun\{f, c};
/**
* Fetches orders based off of the arguments, filters data, and imports to database
*/
final class ImportOrdersFromApi
{
public function __construct(ApiClient $client, OrderRepository $orderRepository, SaveOrders $saveOrders) {
// ...
}
public function __invoke(ImportOrderRequest $req): void {
f\compose(
$this->persistApiOrders(),
$this->removeAlreadyImportedOrders(),
$this->fetchOrdersFromApi()
)($req);
}
private function persistApiOrders(): callable {
// important that this is an c\each so that it will consume the iterable chain
return f\compose(
c\each($this->saveOrders), // saveOrders has a signature of `__invoke(iterable Order[]) => void`
c\chunk(50), // chunk to persist many at once
c\map(function(array $apiOrder) {
return Order::createFromApiData($apiOrder);
})
);
}
private function removeAlreadyImportedOrders(): callable {
return f\compose(
c\flatMap(function(array $apiOrders) {
$apiOrderIds = array_column($apiOrders, 'order_id');
/** array of order id => order entity */
$orders = $this->orderRepository->findByApiOrderIds($ids);
return f\filter(function(array $apiOrder) use ($orders) {
return !array_key_exists($apiOrder['order_id'], $orders);
}, $apiOrders);
}),
// chunk by 50 to save on database requests
c\chunk(50)
);
}
/** Returns an iterable of api orders */
private function fetchOrdersFromApi(): callable {
return function(ImportOrderRequest $req) {
yield from $this->apiClient->fetch(/* pass in req args */);
};
}
}
$res = all(function ($v) {
return $v % 2 == 0;
}, [2, 4, 6]);
expect($res)->equal(true);
$res = all(function ($v) {
return $v % 2 == 0;
}, [1, 2, 4, 6]);
expect($res)->equal(false);
$res = any(function ($v) {
return $v % 2 == 0;
}, [1, 3, 4, 5]);
expect($res)->equal(true);
$res = any(function ($v) {
return $v % 2 == 0;
}, [1, 3, 5]);
expect($res)->equal(false);
$res = arrayCompact([1, 2, null, null, 3]);
expect(\array_values($res))->equal([1, 2, 3]);
$res = arrayFilter(partial(op, '<', 2), [1, 2, 3]);
expect($res)->equal([1]);
$res = arrayFilter(partial(op, '<', 2), range(1, 3));
expect($res)->equal([1]);
$res = arrayMap(partial(op, '*', 2), [1, 2, 3]);
expect($res)->equal([2, 4, 6]);
$res = arrayMap(partial(op, '*', 2), range(1, 3));
expect($res)->equal([2, 4, 6]);
$res = arrayReindex(function ($v) {
return $v['id'];
}, [['id' => 2], ['id' => 3], ['id' => 1]]);
expect($res)->equal([2 => ['id' => 2], 3 => ['id' => 3], 1 => ['id' => 1]]);
$results = arrayMap(arrayWrap, [1, 'abc', ['a' => 1]]);
expect($results)->equal([[1], ['abc'], [['a' => 1]]]);
$results = arrayMap(arrayWrap, [[], [1, 2, 3]]);
expect($results)->equal([[], [1, 2, 3]]);
$obj = new \StdClass();
$obj = assign($obj, ['a' => 1, 'b' => 2]);
expect($obj->a)->equal(1);
expect($obj->b)->equal(2);
$res = chain([1], range(2, 3));
expect(toArray($res))->equal([1, 2, 3]);
$res = chunk(2, [1, 2, 3, 4]);
expect(toArray($res))->equal([[1, 2], [3, 4]]);
$res = chunk(3, [1, 2, 3, 4]);
expect(toArray($res))->equal([[1, 2, 3], [4]]);
$items = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc'];
$chunks = chunkBy(function (string $item) {
return $item[0];
// return first char
}, $items);
expect(toArray($chunks))->equal([['aa', 'ab', 'ac'], ['ba', 'bb', 'bc'], ['ca', 'cb', 'cc']]);
$items = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc'];
$chunks = chunkBy(function (string $item) {
return $item[0];
// return first char
}, $items, 2);
expect(toArray($chunks))->equal([['aa', 'ab'], ['ac'], ['ba', 'bb'], ['bc'], ['ca', 'cb'], ['cc']]);
$res = compact([1, null, 2, 3, null, null, 4]);
expect(toArray($res))->equal([1, 2, 3, 4]);
$mul2 = Curried\op('*')(2);
$add3 = Curried\op('+')(3);
$add3ThenMul2 = compose($mul2, $add3);
$res = $add3ThenMul2(5);
expect($res)->equal(16);
$res = compose(Curried\reduce(function ($acc, $v) {
return $acc + $v;
}, 0), function () {
yield from [1, 2, 3];
})();
expect($res)->equal(6);
$res = construct(\ArrayObject::class, [1, 2, 3]);
expect($res->count())->equal(3);
$res = curry(_idArgs::class, 2)(1)(2)(3);
expect($res)->equal([1, 2, 3]);
$res = differenceWith(partial(op, '==='), [1, 2, 3, 4, 5], [2, 3, 4]);
expect(toArray($res))->equal([1, 5]);
$res = null;
$died = false;
$dump = function ($v) use(&$res) {
$res = $v;
};
$die = function () use(&$died) {
$died = true;
};
dd(1, $dump, $die);
expect($res)->equal(1);
expect($died)->equal(true);
$res = drop(2, range(0, 3));
expect(toArray($res))->equal([2, 3]);
$res = dropWhile(Curried\op('>')(0), [2, 1, 0, 1, 2]);
expect(toArray($res))->equal([0, 1, 2]);
$state = [(object) ['id' => 1], (object) ['id' => 2]];
each(function ($item) {
$item->id += 1;
}, $state);
expect([$state[0]->id, $state[1]->id])->equal([2, 3]);
$values = filter(partial(op, '>', 2), [1, 2, 3, 4]);
// keep all items that are greater than 2
expect(toArray($values))->equal([3, 4]);
$res = filterKeys(Curried\inArray(['a', 'b']), ['a' => 1, 'b' => 2, 'c' => 3]);
expect(toArrayWithKeys($res))->equal(['a' => 1, 'b' => 2]);
$res = flatMap(function ($v) {
return [-$v, $v];
}, range(1, 3));
expect(toArray($res))->equal([-1, 1, -2, 2, -3, 3]);
$res = flatten([1, [2, [3, [4]]]]);
expect(toArray($res))->equal([1, 2, 3, 4]);
$res = flatten([1, [2, [3]]], 1);
expect(toArray($res))->equal([1, 2, [3]]);
$res = flatten([1, [2]], 0);
expect(toArray($res))->equal([1, [2]]);
$res = flip(['a' => 0, 'b' => 1]);
expect(toArray($res))->equal(['a', 'b']);
$res = fromPairs([['a', 1], ['b', 2]]);
expect(toArrayWithKeys($res))->equal(['a' => 1, 'b' => 2]);
$items = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc'];
$groupedItems = groupBy(function (string $item) {
return $item[0];
// return first char
}, $items);
expect(toArray($groupedItems))->equal([['aa', 'ab', 'ac'], ['ba', 'bb', 'bc'], ['ca', 'cb', 'cc']]);
$items = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc'];
$groupedItems = groupBy(function (string $item) {
return $item[0];
// return first char
}, $items, 2);
expect(toArray($groupedItems))->equal([['aa', 'ab'], ['ac'], ['ba', 'bb'], ['bc'], ['ca', 'cb'], ['cc']]);
$res = hasIndexIn(['a', 'b', 'c'], ['a' => ['b' => ['c' => null]]]);
expect($res)->equal(true);
$res = hasIndexIn(['a', 'b', 'c'], ['a' => ['b' => []]]);
expect($res)->equal(false);
$res = head([1, 2, 3]);
expect($res)->equal(1);
$res = head([]);
expect($res)->equal(null);
$res = inArray([1, 2, 3], 2);
expect($res)->equal(true);
$res = index('a', ['a' => 1]);
expect($res)->equal(1);
$res = index('a', ['b' => 1], 2);
expect($res)->equal(2);
class MyClass implements \ArrayAccess
{
private $container = [];
public function __construct()
{
$this->container = ['one' => 1, 'two' => 2];
}
public function offsetExists($offset)
{
return isset($this->container[$offset]);
}
public function offsetGet($offset)
{
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
public function offsetSet($offset, $value)
{
/* ... */
}
public function offsetUnset($offset)
{
/* ... */
}
}
$object = new MyClass();
expect(index('two', $object))->equal(2);
expect(index('three', $object, 'else'))->equal('else');
$res = indexIn(['a', 'b'], ['a' => ['b' => 1]]);
expect($res)->equal(1);
$res = indexIn(['a', 'b'], ['a' => ['c' => 1]], 2);
expect($res)->equal(2);
$res = indexOf(partial(op, '==', 'b'), ['a', 'b', 'c']);
expect($res)->equal(1);
expect(isNull(null))->equal(true);
expect(isNull(0))->equal(false);
expect(iter([1, 2, 3]))->instanceof('Iterator');
expect(iter(new \ArrayIterator([1, 2, 3])))->instanceof('Iterator');
$obj = (object) ['a' => 1, 'b' => 2];
expect(iter($obj))->instanceof('Iterator');
expect(toArrayWithKeys(iter($obj)))->equal(['a' => 1, 'b' => 2]);
$a = new class implements \IteratorAggregate
{
public function getIterator()
{
return new \ArrayIterator([1, 2, 3]);
}
};
expect(iter($a))->instanceof('Iterator');
expect(toArray(iter($a)))->equal([1, 2, 3]);
expect(iter('abc'))->instanceof('Iterator');
expect(toArray(iter('abc')))->equal(['a', 'b', 'c']);
expect(function () {
iter(1);
})->throw('LogicException', 'Iter could not be converted into an iterable.');
$res = join(",", range(1, 3));
expect($res)->equal("1,2,3");
$keys = keys(['a' => 1, 'b' => 2]);
expect(toArray($keys))->equal(['a', 'b']);
$values = map(partial(op, '*', 2), [1, 2, 3, 4]);
expect(toArray($values))->equal([2, 4, 6, 8]);
$data = iter('abcd');
[$totalSort, $values] = mapAccum(function ($acc, $value) {
return [$acc + 1, ['name' => $value, 'sort' => $acc]];
}, iter('abcd'), 0);
expect($totalSort)->equal(4);
expect($values)->equal([['name' => 'a', 'sort' => 0], ['name' => 'b', 'sort' => 1], ['name' => 'c', 'sort' => 2], ['name' => 'd', 'sort' => 3]]);
$keys = mapKeys(partial(op, '.', '_'), ['a' => 1, 'b' => 2]);
expect(toArrayWithKeys($keys))->equal(['a_' => 1, 'b_' => 2]);
$keys = mapKeyValue(function ($kv) {
[$key, $value] = $kv;
return ["{$key}_", $value * $value];
}, ['a' => 1, 'b' => 2]);
expect(toArrayWithKeys($keys))->equal(['a_' => 1, 'b_' => 4]);
$values = mapOn(['a' => partial(op, '*', 3), 'b' => partial(op, '+', 1)], ['a' => 1, 'b' => 2, 'c' => 3]);
expect(toArray($values))->equal([3, 3, 3]);
expect(nullable('intval', '0'))->equal(0);
expect(nullable('intval', null))->equal(null);
$state = [(object) ['id' => 1], (object) ['id' => 2]];
onEach(function ($item) {
$item->id += 1;
}, $state);
expect([$state[0]->id, $state[1]->id])->equal([2, 3]);
$res = op('<', 2, 1);
expect($res)->equal(true);
$obj = new stdClass();
$ops = [['==', [1, 1]], ['eq', [2, 2]], ['!=', [1, 2]], ['neq', [2, 3]], ['===', [$obj, $obj]], ['!==', [new stdClass(), new stdClass()]], ['>', [1, 2]], ['gt', [1, 3]], ['>=', [1, 2]], ['gte', [1, 1]], ['<', [2, 1]], ['lt', [3, 1]], ['<=', [2, 1]], ['lte', [1, 1]]];
foreach ($ops as list($op, list($b, $a))) {
$res = op($op, $b, $a);
expect($res)->equal(true);
}
$ops = [['+', [2, 3], 5], ['-', [2, 3], 1], ['*', [2, 3], 6], ['**', [2, 3], 9], ['/', [2, 3], 1.5], ['%', [2, 3], 1], ['.', ['b', 'a'], 'ab']];
foreach ($ops as list($op, list($b, $a), $expected)) {
$res = op($op, $b, $a);
expect($res)->equal($expected);
}
$add2 = Curried\op('+')(2);
$mul3 = partial(op, '*', 3);
$sub4 = Curried\op('-')(4);
// ((2 + 2) * 3) - 4
$res = compose($sub4, $mul3, $add2)(2);
expect($res)->equal(8);
$res = pad(5, [1, 2, 3]);
expect(toArray($res))->equal([1, 2, 3, null, null]);
$res = pad(5, [1, 2, 3], 0);
expect(toArray($res))->equal([1, 2, 3, 0, 0]);
$res = pad(5, [1, 2, 3, 4, 5]);
expect(toArray($res))->equal([1, 2, 3, 4, 5]);
$res = pad(5, [1, 2, 3, 4, 5, 6]);
expect(toArray($res))->equal([1, 2, 3, 4, 5, 6]);
$res = pad(3, ['a' => 1, 'b' => 2]);
expect(toArrayWithKeys($res))->equal([1, 2, null]);
$fn = function ($a, $b, $c) {
return ($a + $b) * $c;
};
$fn = partial($fn, 1, 2);
// apply the two arguments (a, b) and return a new function with signature (c) -> d
expect($fn(3))->equal(9);
$fn = function ($a, $b, $c) {
return ($a + $b) * $c;
};
// _() represents a placeholder for parameter b.
$fn = partial($fn, 1, _(), 3);
// create the new func with signature (b) -> d
expect($fn(2))->equal(9);
$fn = function ($a, $b) {
return [$a, $b];
};
$fn = partial($fn, 1, 2);
expect($fn())->equal([1, 2]);
list($left, $right) = partition(function ($v) {
return $v < 3 ? 0 : 1;
}, [1, 2, 3, 4]);
expect([$left, $right])->equal([[1, 2], [3, 4]]);
$res = pick(['a', 'b'], ['a' => 1, 'b' => 2, 'c' => 3]);
expect($res)->equal(['a' => 1, 'b' => 2]);
$res = arrayMap(Curried\pick(['id', 'name']), [['id' => 1, 'name' => 'Foo', 'slug' => 'foo'], ['id' => 2, 'name' => 'Bar', 'slug' => 'bar']]);
expect($res)->equal([['id' => 1, 'name' => 'Foo'], ['id' => 2, 'name' => 'Bar']]);
$res = pickBy(Curried\spread(function (string $key, int $value) : bool {
return $value % 2 === 0;
}), ['a' => 1, 'b' => 2, 'c' => 3]);
expect($res)->equal(['b' => 2]);
$add3 = Curried\op('+')(3);
$mul2 = Curried\op('*')(2);
$add3ThenMul2 = pipe($add3, $mul2);
$res = $add3ThenMul2(5);
expect($res)->equal(16);
$res = pipe(function () {
yield from [1, 2, 3];
}, Curried\reduce(function ($acc, $v) {
return $acc + $v;
}, 0))();
expect($res)->equal(6);
$res = product([1, 2], [3, 4], [5, 6]);
expect(toArray($res))->equal([[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]);
$obj = new \StdClass();
$obj->id = 1;
$res = prop('id', $obj);
expect($res)->equal(1);
$obj = new \StdClass();
$res = prop('id', $obj, 2);
expect($res)->equal(2);
$obj = new \StdClass();
$obj->id = 1;
$obj->child = new \StdClass();
$obj->child->id = 2;
$res = propIn(['child', 'id'], $obj);
expect($res)->equal(2);
$obj = new \StdClass();
$obj->id = 1;
$obj->child = new \StdClass();
$res = propIn(['child', 'id'], $obj, 3);
expect($res)->equal(3);
$res = range(1, 3);
expect(toArray($res))->equal([1, 2, 3]);
php
$res = range(3, 1);
expect(toArray($res))->equal([3, 2, 1]);
php
expect(function () {
toArray(range(1, 2, -1));
})->throw(\InvalidArgumentException::class);
expect(function () {
toArray(range(2, 1, 1));
})->throw(\InvalidArgumentException::class);
php
$res = reduce(function ($acc, $v) {
return $acc + $v;
}, range(1, 3), 0);
expect($res)->equal(6);
php
$res = reduceKeyValue(function ($acc, $kv) {
[$key, $value] = $kv;
return $acc . $key . $value;
}, fromPairs([['a', 1], ['b', 2]]), "");
expect($res)->equal("a1b2");
php
$res = reindex(function ($v) {
return $v['id'];
}, [['id' => 2], ['id' => 3], ['id' => 1]]);
expect(toArrayWithKeys($res))->equal([2 => ['id' => 2], 3 => ['id' => 3], 1 => ['id' => 1]]);
php
$i = 0;
$res = retry(function () use(&$i) {
$i += 1;
if ($i <= 1) {
throw new \Exception('bad');
}
return $i;
});
expect($res)->equal(2);
php
expect(function () {
$i = 0;
retry(function () use(&$i) {
$i += 1;
throw new \Exception((string) $i);
}, 5);
})->throw('Exception', '6');
php
$i = 0;
expect(function () {
$res = retry(function () use(&$i) {
$i += 1;
throw new \Exception((string) $i);
}, function ($numRetries, \Throwable $t = null) {
return $numRetries < 2;
});
})->throw('Exception', '2');
php
$res = retry(function ($numRetries) {
if (!$numRetries) {
throw new Exception('bad');
}
return $numRetries;
}, 2);
expect($res)->equal(1);
php
$res = search(function ($v) {
return $v['id'] == 2;
}, [['id' => 1], ['id' => 2], ['id' => 3]]);
expect($res)->equal(['id' => 2]);
php
$res = search(function ($v) {
return false;
}, [['id' => 1], ['id' => 2], ['id' => 3]]);
expect($res)->equal(null);
php
$res = setIndex('a', 1, []);
expect($res['a'])->equal(1);
php
$res = setProp('a', 1, (object) []);
expect($res->a)->equal(1);
php
$sliced = slice(1, range(0, 4), 2);
expect(toArray($sliced))->equal([1, 2]);
php
$sliced = slice(2, range(0, 4));
expect(toArray($sliced))->equal([2, 3, 4]);
php
$i = 0;
$gen = function () use(&$i) {
foreach (range(0, 4) as $v) {
$i = $v;
(yield $i);
}
};
$sliced = toArray(slice(1, $gen(), 2));
expect($sliced)->equal([1, 2]);
expect($i)->equal(2);
php
$data = [['id' => 1, 'name' => 'A'], ['id' => 2, 'name' => 'B'], ['id' => 3, 'name' => 'C']];
$res = sortFromArray(Curried\index('id'), [2, 3, 1], $data);
expect(arrayMap(Curried\index('name'), $res))->equal(['B', 'C', 'A']);
php
expect(function () {
$data = [['id' => 1]];
$res = sortFromArray(Curried\index('id'), [], $data);
})->throw(\LogicException::class, 'Cannot sort element key 1 because it does not exist in the ordered elements.');
php
$res = spread(function ($a, $b) {
return $a . $b;
}, ['a', 'b']);
expect($res)->equal('ab');
php
$res = arrayMap(Curried\spread(function (string $first, int $second) {
return $first . $second;
}), [['a', 1], ['b', 2]]);
expect($res)->equal(['a1', 'b2']);
php
$res = take(2, range(0, 10));
expect(toArray($res))->equal([0, 1]);
php
$res = takeWhile(Curried\op('>')(0), [2, 1, 0, 1, 2]);
expect(toArray($res))->equal([2, 1]);
php
$loggedValues = [];
$res = tap(function (string $v) use(&$loggedValues) {
$loggedValues[] = $v;
}, 'abc');
expect([$loggedValues[0], $res])->equal(['abc', 'abc']);
php
expect(function () {
throwIf(function (int $value) {
return new RuntimeException('Error: ' . $value);
}, function (int $value) {
return $value === 0;
}, 0);
})->throw(RuntimeException::class, 'Error: 0');
php
$res = throwIf(function (int $value) {
return new RuntimeException('Error: ' . $value);
}, function (int $value) {
return $value === 0;
}, 1);
expect($res)->equal(1);
php
$res = toArray((function () {
(yield 1);
(yield 2);
(yield 3);
})());
expect($res)->equal([1, 2, 3]);
php
$res = compose(toArray, id)((function () {
(yield 1);
(yield 2);
(yield 3);
})());
expect($res)->equal([1, 2, 3]);
php
$res = toPairs(['a' => 1, 'b' => 2]);
expect(toArray($res))->equal([['a', 1], ['b', 2]]);
php
$data = ['a' => ['b' => ['c' => 3]]];
$data = updateIndexIn(['a', 'b', 'c'], function ($v) {
return $v * $v;
}, $data);
expect($data)->equal(['a' => ['b' => ['c' => 9]]]);
php
expect(function () {
$data = ['a' => ['b' => ['c' => 9]]];
updateIndexIn(['a', 'c', 'c'], function () {
}, $data);
})->throw(\RuntimeException::class, 'Could not updateIn because the keys a -> c -> c could not be found.');
php
$res = values(['a' => 1, 'b' => 2]);
expect(toArrayWithKeys($res))->equal([1, 2]);
php
$if = function ($v) {
return $v == 3;
};
$then = function ($v) {
return $v * $v;
};
$res = when($if, $then, 3);
expect($res)->equal(9);
php
$if = function ($v) {
return $v == 3;
};
$then = function ($v) {
return $v * $v;
};
$res = when($if, $then, 4);
expect($res)->equal(4);
php
$fn = withState(function ($state, $v) {
return [$state + 1, $state . ': ' . $v];
}, 1);
$res = arrayMap($fn, iter('abcd'));
expect($res)->equal(['1: a', '2: b', '3: c', '4: d']);
php
$data = flip(iter('abcd'));
$res = within(['a', 'c'], $data);
expect(toArrayWithKeys($res))->equal(['a' => 0, 'c' => 2]);
php
$data = flip(iter('abcd'));
$res = without(['a', 'c'], $data);
expect(toArrayWithKeys($res))->equal(['b' => 1, 'd' => 3]);