Download the PHP package krak/fn without Composer
On this page you can find all versions of the php package krak/fn. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package fn
Short Description Functional library for php with proper currying
License MIT
Informations about the package fn
Fun
Yet another functional library for PHP. What makes this library special is that it uses PHP Parser to generate curried versions of the non-curried implementations for best performance.
Installation
Install with composer at krak/fn
Usage
All functions are defined in Krak\Fun
, are not curried, and are data last. Curried versions of functions are defined Kran\Fun\Curried
. Constants are also generated per function in Krak\Fun\Consts
.
Check the src/fn.php
for examples of all the functions.
Fun API
In addition to importing the functions/consts individually, you can also utilize the f
and c
namespaces as a shorthand which make using the library a lot easier.
The f
namespace holds the standard functions basically copied over verbatim from the Krak\Fun
namespace.
The c
namespace contains all of the curried functions and constant definitions.
One great way to use the consts is with compose or pipe chains:
Constants
This library generates constants with same name as the function they were generated from where their value is the fully qualified name of the function.
PHP (unfortunately) will treat strings as callables if they resolve to a function name. So generating constants with the same name as functions allows us to support a neat first class function type syntax.
The above is valid php and will work because c\toArray resolves to Krak\\Fun\\toArray
which php will treat as a valid callable.
This is great for compose chains and partial application:
The op
function is defined as op($operator, $b, $a)
. Essentially, what we did was call: partial('Krak\\Fun\\op', '*', 3)
.
Currying
All functions that are curryable have generated curry functions. A function is curryable if it has more than one required argument or one required argument with any number of optional arguments.
These function definitions aren't curryable:
These are:
Given a function definition like:
the curried verison would look like:
Debugging
If you have a function compose chain and want to debug/test the result of any of the functions, you can do something like the following examples:
-
Debug a single value:
- Debug an iterable:
Using Compose Chains for Readable Code
One of my favorite features of using this library is building compose chains in a way that make your application services a lot easier to read and follow along with.
Docs
Docs are generated with make docs
. This uses Krak Peridocs to actually generate the documentation from the peridot tests.
Code Generation
The constants and curried functions are generated with make code
.
Tests
Tests are run via make test
and are stored in the test
directory. We use peridot for testing.
API
zip |
all(callable $predicate, iterable $iter): bool
Name: Krak\Fun\all
Returns true if the predicate returns true on all of the items:
Returns false if the predicate returns false on any of the items:
any(callable $predicate, iterable $iter): bool
Name: Krak\Fun\any
Returns true if the predicate returns true on any of the items:
Returns false if the predicate returns false on all of the items:
arrayCompact(iterable $iter): array
Name: Krak\Fun\arrayCompact
It will remove all nulls from an iterable and return an array:
Keep in mind that the keys will be preserved when using arrayCompact, so make sure to use array_values if you want to ignore keys.
arrayFilter(callable $fn, iterable $data): array
Name: Krak\Fun\arrayFilter
Alias of array_filter:
Filters iterables as well as arrays:
arrayMap(callable $fn, iterable $data): array
Name: Krak\Fun\arrayMap
Alias of array_map:
Maps iterables as well as arrays:
arrayReindex(callable $fn, iterable $iter): array
Name: Krak\Fun\arrayReindex
Re-indexes a collection via a callable into an associative array:
arrayWrap($value)
Name: Krak\Fun\arrayWrap
Wraps any non list array into an array:
List based arrays are left as is:
Note: array_is_list
which requires php 8.1 or symfony/polyfill-php81
assign($obj, iterable $iter)
Name: Krak\Fun\assign
Assigns iterable keys and values to an object:
chain(iterable ...$iters)
Name: Krak\Fun\chain
Chains iterables together into one iterable:
chunk(int $size, iterable $iter): iterable
Name: Krak\Fun\chunk
Chunks an iterable into equal sized chunks.:
If there is any remainder, it is yielded as is:
chunkBy(callable $fn, iterable $iter, ?int $maxSize = null): iterable
Name: Krak\Fun\chunkBy
Chunks items together off of the result from the callable:
Allows a maxSize to prevent chunks from exceeding a limit:
compact(iterable $iter): iterable
Name: Krak\Fun\compact
Removes all null values from an iterable:
compose(callable ...$fns)
Name: Krak\Fun\compose
Composes functions together. compose(f, g)(x) == f(g(x)):
Allows an empty initial argument:
construct($className, ...$args)
Name: Krak\Fun\construct
Constructs (instantiates) a new class with the given arguments:
curry(callable $fn, int $num = 1)
Name: Krak\Fun\curry
currys the given function $n times:
Given a function definition: (a, b) -> c. A curried version will look like (a) -> (b) -> c
differenceWith(callable $cmp, iterable $a, iterable $b)
Name: Krak\Fun\differenceWith
Takes the difference between two iterables with a given comparator:
dd($value, callable $dump = null, callable $die = null)
Name: Krak\Fun\dd
dumps and dies:
drop(int $num, iterable $iter): iterable
Name: Krak\Fun\drop
Drops the first num items from an iterable:
dropWhile(callable $predicate, iterable $iter): iterable
Name: Krak\Fun\dropWhile
Drops elements from the iterable while the predicate returns true:
each(callable $handle, iterable $iter)
Name: Krak\Fun\each
Invokes a callable on each item in an iterable:
Normally using php foreach should suffice for iterating over an iterable; however, php variables in foreach loops are not scoped whereas closures are.
filter(callable $predicate, iterable $iter): iterable
Name: Krak\Fun\filter
Lazily filters an iterable off of a predicate that should return true or false. If true, keep the data, else remove the data from the iterable:
filterKeys(callable $predicate, iterable $iter): iterable
Name: Krak\Fun\filterKeys
Filters an iterable off of the keys:
flatMap(callable $map, iterable $iter): iterable
Name: Krak\Fun\flatMap
Maps and then flattens an iterable:
flatMap is perfect for when you want to map an iterable and also add elements to the resulting iterable.
flatten(iterable $iter, $levels = INF): iterable
Name: Krak\Fun\flatten
Flattens nested iterables into a flattened set of elements:
Can flatten a specific number of levels:
Flattening zero levels does nothing:
flip(iterable $iter): iterable
Name: Krak\Fun\flip
Flips the keys => values of an iterable to values => keys:
fromPairs(iterable $iter): iterable
Name: Krak\Fun\fromPairs
Converts an iterable of tuples [$key, $value] into an associative iterable:
groupBy(callable $fn, iterable $iter, ?int $maxSize = null): iterable
Name: Krak\Fun\groupBy
Alias of chunkBy
Groups items together off of the result from the callable:
Allows a maxSize to prevent groups from exceeding a limit:
hasIndexIn(array $keys, array $data): bool
Name: Krak\Fun\hasIndexIn
Checks if a nested index exists in the given data:
Returns false if any of the indexes do not exist in the data:
head(iterable $iter)
Name: Krak\Fun\head
Returns the fist element in an iterable:
But returns null if the iterable is empty:
inArray(array $set, $item): bool
Name: Krak\Fun\inArray
Checks if an item is within an array of items:
index($key, $data, $else = null)
Name: Krak\Fun\index
Accesses an index in an array:
If no value exists at the given index, $else will be returned:
Also works with objects that implement ArrayAccess:
indexIn(array $keys, array $data, $else = null)
Name: Krak\Fun\indexIn
Accesses a nested index in a deep array structure:
If any of the indexes do not exist, $else will be returned:
indexOf(callable $predicate, iterable $iter)
Name: Krak\Fun\indexOf
Searches for an element and returns the key if found:
isNull($val)
Name: Krak\Fun\isNull
alias for is_null:
iter($iter): \Iterator
Name: Krak\Fun\iter
Converts any iterable into a proper instance of Iterator.
Can convert arrays:
Can convert an Iterator:
Can convert objects:
Can convert any iterable:
Can convert strings:
Will throw an exception otherwise:
join(string $sep, iterable $iter)
Name: Krak\Fun\join
Joins an iterable with a given separator:
keys(iterable $iter): iterable
Name: Krak\Fun\keys
Yields only the keys of an in iterable:
map(callable $predicate, iterable $iter): iterable
Name: Krak\Fun\map
Lazily maps an iterable's values to a different set:
mapAccum(callable $fn, iterable $iter, $acc = null)
Name: Krak\Fun\mapAccum
Maps a function to each element of a list while passing in an accumulator to accumulate over every iteration:
Note: mapAccum converts the interable into an array and is not lazy like most of the other functions in this library
mapKeys(callable $predicate, iterable $iter): iterable
Name: Krak\Fun\mapKeys
Lazily maps an iterable's keys to a different set:
mapKeyValue(callable $fn, iterable $iter): iterable
Name: Krak\Fun\mapKeyValue
Lazily maps an iterable's key/value tuples to a different set:
mapOn(array $maps, iterable $iter): iterable
Name: Krak\Fun\mapOn
Maps values on specific keys:
nullable(callable $fn, $value)
Name: Krak\Fun\nullable
Performs the callable if the value is not null:
Returns null if the value is null:
onEach(callable $handle, iterable $iter)
Name: Krak\Fun\onEach
Duplicate of each.
Invokes a callable on each item in an iterable:
Normally using php foreach should suffice for iterating over an iterable; however, php variables in foreach loops are not scoped whereas closures are.
op(string $op, $b, $a)
Name: Krak\Fun\op
op evaluates binary operations. It expects the right hand operator first which makes most sense when currying or partially applying the op function.
When reading the op func, it should be read: evaluate $op with $b with $a
e.g.:
Evaluates two values with a given operator:
Supports equality operators:
Supports other operators:
Is more useful partially applied or curried:
pad(int $size, iterable $iter, $padValue = null): iterable
Name: Krak\Fun\pad
Pads an iterable to a specific size:
Allows custom pad values:
Pads nothing if iterable is the same size as pad size:
Pads nothing if iterable is greater than pad size:
Ignores keys of original iterable:
partial(callable $fn, ...$appliedArgs)
Name: Krak\Fun\partial
Partially applies arguments to a function. Given a function signature like f = (a, b, c) -> d, partial(f, a, b) -> (c) -> d:
You can also use place holders when partially applying:
Full partial application also works:
partition(callable $partition, iterable $iter, int $numParts = 2): array
Name: Krak\Fun\partition
Splits an iterable into different arrays based off of a predicate. The predicate should return the index to partition the data into:
pick(iterable $fields, array $data): array
Name: Krak\Fun\pick
Picks only the given fields from a structured array:
Can be used in curried form:
pickBy(callable $pick, array $data): array
Name: Krak\Fun\pickBy
Picks only the fields that match the pick function from a structured array:
pipe(callable ...$fns)
Name: Krak\Fun\pipe
Creates a function that pipes values from one func to the next.:
Allows an empty initial argument:
pipe
and compose
are sister functions and do the same thing except the functions are composed in reverse order. pipe(f, g)(x) = g(f(x))
product(iterable ...$iters): iterable
Name: Krak\Fun\product
Creates a cartesian product of multiple sets:
prop(string $key, $data, $else = null)
Name: Krak\Fun\prop
Accesses a property from an object:
If no property exists, it will return the $else value:
propIn(array $props, $obj, $else = null)
Name: Krak\Fun\propIn
Accesses a property deep in an object tree:
If any property is missing in the tree, it will return the $else value:
range($start, $end, $step = null)
Name: Krak\Fun\range
Creates an iterable of a range of values starting from $start going to $end inclusively incrementing by $step:
It also allows a decreasing range:
An exception will be thrown if the $step provided goes in the wrong direction:
reduce(callable $reduce, iterable $iter, $acc = null)
Name: Krak\Fun\reduce
Reduces an iterable into a single value:
reduceKeyValue(callable $reduce, iterable $iter, $acc = null)
Name: Krak\Fun\reduceKeyValue
Reduces an iterables key value pairs into a value:
reindex(callable $fn, iterable $iter): iterable
Name: Krak\Fun\reindex
Re-indexes a collection via a callable:
retry(callable $fn, $shouldRetry = null)
Name: Krak\Fun\retry
Executes a function and retries if an exception is thrown:
Only retries $maxTries times else it gives up and bubbles the exception:
Retries until $shouldRetry returns false:
Sends numRetries into the main fn:
Keep in mind that maxTries determines the number of re-tries. This means the function will execute maxTries + 1 times since the first invocation is not a retry.
search(callable $predicate, iterable $iter)
Name: Krak\Fun\search
Searches for an element in a collection where the callable returns true:
Returns null if no element was found:
setIndex($key, $value, array $data)
Name: Krak\Fun\setIndex
Sets an index in an array:
setIndexIn(array $keys, $value, array $data)
Name: Krak\Fun\setIndexIn
Sets a nested index in an array:
setProp(string $key, $value, $data)
Name: Krak\Fun\setProp
Sets a property in an object:
slice(int $start, iterable $iter, $length = INF): iterable
Name: Krak\Fun\slice
It takes an inclusive slice from start to a given length of an interable:
If length is not supplied it default to the end of the iterable:
will not consume the iterator once the slice has been yielded:
sortFromArray(callable $fn, array $orderedElements, iterable $iter): array
Name: Krak\Fun\sortFromArray
Sort an iterable with a given array of ordered elements to sort by:
Throws an exception if any item in the iterable is not within the orderedElements:
I've found this to be very useful when you fetch records from a database with a WHERE IN clause, and you need to make sure the results are in the same order as the ids in the WHERE IN clause.
spread(callable $fn, array $data)
Name: Krak\Fun\spread
Spreads an array of arguments to a callable:
Can be used in the curried form to unpack tuple arguments:
Note: this is basically just an alias for call_user_func_array
or simply a functional wrapper around the ...
(spread) operator.
take(int $num, iterable $iter): iterable
Name: Krak\Fun\take
Takes the first num items from an iterable:
takeWhile(callable $predicate, iterable $iter): iterable
Name: Krak\Fun\takeWhile
Takes elements from an iterable while the $predicate returns true:
tap(callable $tap, $value)
Name: Krak\Fun\tap
Calls given tap function on value and returns value:
tap
is useful anytime you need to operate on a value and do not want to modify the return value.
throwIf(callable $throw, callable $if, $value)
Name: Krak\Fun\throwIf
Throws the given exception if value given evaluates to true:
Returns given value if value evaluates to false:
Note: works best with short closures!
toArray(iterable $iter): array
Name: Krak\Fun\toArray
will tranform any iterable into an array:
can also be used as a constant:
toArrayWithKeys(iterable $iter): array
Name: Krak\Fun\toArrayWithKeys
can convert to an array and keep the keys:
toPairs(iterable $iter): iterable
Name: Krak\Fun\toPairs
Transforms an associative array into an iterable of tuples [$key, $value]:
updateIndexIn(array $keys, callable $update, array $data): array
Name: Krak\Fun\updateIndexIn
Updates a nested element within a deep array structure:
Throws an exception if nested key does not exist:
values(iterable $iter): iterable
Name: Krak\Fun\values
Exports only the values of an iterable:
when(callable $if, callable $then, $value)
Name: Krak\Fun\when
Evaluates the given value with the $then callable if the predicate returns true:
But will return the given value if the predicate returns false:
withState(callable $fn, $initialState = null)
Name: Krak\Fun\withState
Decorate a function with accumulating state:
within(array $fields, iterable $iter): \Iterator
Name: Krak\Fun\within
Only allows keys within the given array to stay:
without(array $fields, iterable $iter): \Iterator
Name: Krak\Fun\without
Filters an iterable to be without the given keys:
zip(iterable ...$iters): \Iterator
Name: Krak\Fun\zip
Zips multiple iterables into an iterable n-tuples:
Returns an empty iterable if no iters are present: