Beispiel #1
0
<?php

namespace PHPixme;

/**
 * Take a callable and produce a curried \Closure
 * @param int $arity
 * @param callable = $hof
 * @return \Closure
 * @sig Integer -> Callable (*-> x) -> \Closure (* -> x)
 */
function curry($arity = null, callable $hof = null)
{
    return call_user_func_array(__PRIVATE__::$instance[curry], func_get_args());
}
const curry = __NAMESPACE__ . '\\curry';
__PRIVATE__::$instance[curry] = __PRIVATE__::curryExactly2(function ($arity, $callable) {
    __CONTRACT__::argIsAPositiveOrZeroInt($arity);
    __CONTRACT__::argIsACallable($callable, 1);
    // The function is static so that is easier to recurse,
    // as it shares no state with itself outside its arguments.
    return __PRIVATE__::curryGiven([], $arity, $callable);
});
Beispiel #2
0
<?php

namespace PHPixme;

/**
 * @param callable $hof
 * @param \Traversable= $traversable
 * @return \Closure|mixed
 * @sig Callable (a, b -> a) -> \Traversable[a,b] -> a
 */
function reduce($hof = null, $traversable = null)
{
    return call_user_func_array(__PRIVATE__::$instance[reduce], func_get_args());
}
const reduce = __NAMESPACE__ . '\\reduce';
__PRIVATE__::$instance[reduce] = __PRIVATE__::curryExactly2(function ($hof, $arrayLike) {
    __CONTRACT__::argIsACallable($hof);
    __CONTRACT__::argIsATraversable($arrayLike, 1);
    if ($arrayLike instanceof ReducibleInterface) {
        return $arrayLike->reduce($hof);
    }
    // Equalize the usefulness
    $array = __CONTRACT__::isNonEmpty(__PRIVATE__::traversableToArray($arrayLike));
    $output = current($array);
    next($array);
    while (null !== ($key = key($array))) {
        $output = call_user_func($hof, $output, current($array), $key, $arrayLike);
        next($array);
    }
    return $output;
});
Beispiel #3
0
<?php

namespace PHPixme;

/**
 * ufo, short for the space ship operator, or the three way comparison, a stand in for <=>
 * @sig ($lhs)->($rhs)-> boolean $z
 * @param mixed $lhs
 * @param mixed $rhs
 * @return int|\Closure
 */
function ufo($lhs = null, $rhs = null)
{
    return call_user_func_array(__PRIVATE__::$instance[ufo], func_get_args());
}
const ufo = __NAMESPACE__ . '\\ufo';
__PRIVATE__::$instance[ufo] = __PRIVATE__::curryExactly2(function ($lhs, $rhs) {
    return $lhs != $rhs ? $lhs > $rhs ? 1 : -1 : 0;
});
Beispiel #4
0
<?php

namespace PHPixme;

/**
 * @param Callable $decorator
 * @param Callable $fn
 * @return \Closure
 */
function except($decorator = null, $fn = null)
{
    return call_user_func_array(__PRIVATE__::$instance[except], func_get_args());
}
const except = __NAMESPACE__ . '\\except';
__PRIVATE__::$instance[except] = __PRIVATE__::curryExactly2(function ($predicate, $fn) {
    __CONTRACT__::argIsACallable($predicate);
    __CONTRACT__::argIsACallable($fn, 1);
    return function () use($predicate, $fn) {
        $args = func_get_args();
        return call_user_func_array($predicate, $args) ? null : call_user_func_array($fn, $args);
    };
});
Beispiel #5
0
<?php

namespace PHPixme;

/**
 * xorL, short for logical xor, a stand in for xor keyword
 * @sig ($lhs)->($rhs)-> boolean $z
 * @param mixed $lhs
 * @param mixed $rhs
 * @return boolean|\Closure
 */
function xorL($lhs = null, $rhs = null)
{
    return call_user_func_array(__PRIVATE__::$instance[xorL], func_get_args());
}
const xorL = __NAMESPACE__ . '\\xorL';
__PRIVATE__::$instance[xorL] = __PRIVATE__::curryExactly2(function ($lhs, $rhs) {
    return $lhs xor $rhs;
});
Beispiel #6
0
<?php

namespace PHPixme;

/**
 * map
 * @param callable $hof
 * @param array|FunctorInterface|\Traversable $collection
 * @return \Closure|$collection
 */
function walk($hof = null, $collection = null)
{
    return call_user_func_array(__PRIVATE__::$instance[walk], func_get_args());
}
const walk = __NAMESPACE__ . '\\walk';
__PRIVATE__::$instance[walk] = __PRIVATE__::curryExactly2(function ($hof, $collection) {
    __CONTRACT__::argIsACallable($hof);
    __CONTRACT__::argIsATraversable($collection, 1);
    if ($collection instanceof FunctorInterface) {
        return $collection->walk($hof);
    }
    $array = __PRIVATE__::getArrayFrom($collection);
    if ($array !== null) {
        array_walk($array, $hof, $collection);
    } else {
        foreach (__PRIVATE__::copyTransversable($collection) as $k => $v) {
            call_user_func($hof, $v, $k, $collection);
        }
    }
    return $collection;
});
Beispiel #7
0
<?php

namespace PHPixme;

/**
 * After Decorator
 * Decorate a callable using the return value of the decorated callable as the argument
 * for this decorative function. It does not modify the return value.
 * @param Callable $decorator
 * @param Callable $fn
 * @return \Closure
 * @sig Callable (x->) -> Callable (*->x) -> Closure (*->x)
 */
function after($decorator = null, $fn = null)
{
    return call_user_func_array(__PRIVATE__::$instance[after], func_get_args());
}
const after = __NAMESPACE__ . '\\after';
__PRIVATE__::$instance[after] = __PRIVATE__::curryExactly2(function ($decorator, $fn) {
    __CONTRACT__::argIsACallable($decorator);
    __CONTRACT__::argIsACallable($fn, 1);
    return function () use($decorator, $fn) {
        $value = call_user_func_array($fn, func_get_args());
        call_user_func($decorator, $value);
        return $value;
    };
});
Beispiel #8
0
namespace PHPixme;

/**
 * @param callable $hof
 * @param \Traversable= $traversable
 * @return \Closure|mixed
 * @sig Callable (a, b -> a) -> \Traversable[a,b] -> a
 */
function reduceRight($hof = null, $traversable = null)
{
    return call_user_func_array(__PRIVATE__::$instance[reduceRight], func_get_args());
}
const reduceRight = __NAMESPACE__ . '\\reduceRight';
__PRIVATE__::$instance[reduceRight] = __PRIVATE__::curryExactly2(function ($hof, $arrayLike) {
    __CONTRACT__::argIsACallable($hof);
    __CONTRACT__::argIsATraversable($arrayLike, 1);
    if ($arrayLike instanceof ReducibleInterface) {
        return $arrayLike->reduceRight($hof);
    }
    // Equalize the usefulness
    $array = __CONTRACT__::isNonEmpty(__PRIVATE__::traversableToArray($arrayLike));
    $output = end($array);
    $value = prev($array);
    // Traverse using the internal pointer to avoid creating additional work
    while (($key = key($array)) !== null) {
        $output = call_user_func($hof, $output, $value, $key, $arrayLike);
        $value = prev($array);
    }
    return $output;
});
Beispiel #9
0
<?php

namespace PHPixme;

/**
 * pluckObjectWith
 * Creates a function to access the property of an object
 * @param string $accessor
 * @param Object $container
 * @return \Closure ($object) -> object->accessor
 * @sig String -> Object -> \Closure (->x)
 */
function pluckObjectWith($accessor = null, $container = null)
{
    return call_user_func_array(__PRIVATE__::$instance[pluckObjectWith], func_get_args());
}
const pluckObjectWith = __NAMESPACE__ . '\\pluckObjectWith';
__PRIVATE__::$instance[pluckObjectWith] = __PRIVATE__::curryExactly2(function ($accessor, $container) {
    return $container->{$accessor};
});
Beispiel #10
0
<?php

namespace PHPixme;

/**
 * @param callable $hof
 * @param array|\Traversable|FunctorInterface $traversable
 * @return \Closure|mixed
 * @sig Callable (a -> b) -> \Traversable[a] -> \Traversable[b]
 *
 */
function map($hof = null, $traversable = null)
{
    return call_user_func_array(__PRIVATE__::$instance[map], func_get_args());
}
const map = __NAMESPACE__ . '\\map';
__PRIVATE__::$instance[map] = __PRIVATE__::curryExactly2(function ($hof, $traversable) {
    __CONTRACT__::argIsACallable($hof);
    __CONTRACT__::argIsATraversable($traversable, 1);
    if ($traversable instanceof FunctorInterface) {
        return $traversable->map($hof);
    }
    $output = [];
    foreach (__PRIVATE__::protectTraversable($traversable) as $key => $value) {
        $output[$key] = call_user_func($hof, $value, $key, $traversable);
    }
    return $output;
});
Beispiel #11
0
<?php

namespace PHPixme;

/**
 * callWith
 * Produce a function that calls a function within a array or object
 * @param string $accessor
 * @param object|array $container
 * @return \Closure ($container) -> ((args) -> $container{[$accessor]}(...args))
 * @sig String -> Object|Array -> \Closure (*->x)
 */
function callWith($accessor = null, $container = null)
{
    return call_user_func_array(__PRIVATE__::$instance[callWith], func_get_args());
}
const callWith = __NAMESPACE__ . '\\callWith';
__PRIVATE__::$instance[callWith] = __PRIVATE__::curryExactly2(function ($accessor, $container) {
    $callable = __CONTRACT__::composedIsACallable(is_array($container) ? array_key_exists($accessor, $container) ? $container[$accessor] : null : [$container, $accessor]);
    return function () use($callable) {
        return call_user_func_array($callable, func_get_args());
    };
});
Beispiel #12
0
<?php

/**
 * Created by PhpStorm.
 * User: rgladson
 * Date: 5/12/2016
 * Time: 12:03 PM
 */
namespace PHPixme;

/**
 * Wrap a function in an argument that will eat all but n arguments
 * @param int $arity
 * @param callable = $hof
 * @return \Closure
 * @sig Integer -> Callable (* -> x) -> \Closure (* -> x)
 */
function nAry($arity = null, callable $hof = null)
{
    return call_user_func_array(__PRIVATE__::$instance[nAry], func_get_args());
}
const nAry = __NAMESPACE__ . '\\nAry';
__PRIVATE__::$instance[nAry] = __PRIVATE__::curryExactly2(function ($number = 0, $hof = null) {
    __CONTRACT__::argIsAPositiveOrZeroInt($number);
    __CONTRACT__::argIsACallable($hof, 1);
    return function () use($number, $hof) {
        $args = func_get_args();
        return call_user_func_array($hof, array_slice($args, 0, $number));
    };
});
Beispiel #13
0
<?php

namespace PHPixme;

/**
 * pluckArrayWith
 * Creates a function to access the property of an object
 * @param string $accessor
 * @param array $container
 * @return \Closure ($object) -> object->accessor
 * @sig String -> Array -> \Closure (->x)
 */
function pluckArrayWith($accessor = null, $container = null)
{
    return call_user_func_array(__PRIVATE__::$instance[pluckArrayWith], func_get_args());
}
const pluckArrayWith = __NAMESPACE__ . '\\pluckArrayWith';
__PRIVATE__::$instance[pluckArrayWith] = __PRIVATE__::curryExactly2(function ($accessor, $container) {
    return $container[$accessor];
});
Beispiel #14
0
<?php

namespace PHPixme;

/**
 * Group a traversable by a return value, separating them out into [groupName=>[value...]]
 * @param callable $fn
 * @param array|\Traversable $arrayLike
 * @return array|\Closure
 */
function group($fn = null, $arrayLike = null)
{
    return call_user_func_array(__PRIVATE__::$instance[group], func_get_args());
}
const group = __NAMESPACE__ . '\\group';
__PRIVATE__::$instance[group] = __PRIVATE__::curryExactly2(function ($fn, $arrayLike) {
    __CONTRACT__::argIsACallable($fn);
    __CONTRACT__::argIsATraversable($arrayLike, 1);
    if ($arrayLike instanceof GroupableInterface) {
        return $arrayLike->group($fn);
    }
    $output = [];
    foreach (__PRIVATE__::protectTraversable($arrayLike) as $key => $value) {
        $output[call_user_func($fn, $value, $key, $arrayLike)][] = $value;
    }
    return $output;
});
Beispiel #15
0
<?php

namespace PHPixme;

/**
 * partitionWithKey
 * Like filter, but keeps both sides of the comparison. ["true"=>[[key, value]...], "false"=>[[key, value]...]]
 * @param callable $fn
 * @param array|\Traversable $arrayLike
 * @return array|\Closure
 */
function partitionWithKey($fn = null, $arrayLike = null)
{
    return call_user_func_array(__PRIVATE__::$instance[partitionWithKey], func_get_args());
}
const partitionWithKey = __NAMESPACE__ . '\\partitionWithKey';
__PRIVATE__::$instance[partitionWithKey] = __PRIVATE__::curryExactly2(function ($fn, $arrayLike) {
    __CONTRACT__::argIsACallable($fn);
    __CONTRACT__::argIsATraversable($arrayLike, 1);
    if ($arrayLike instanceof GroupableInterface) {
        return $arrayLike->partitionWithKey($fn);
    }
    $output = ["false" => [], "true" => []];
    foreach (__PRIVATE__::protectTraversable($arrayLike) as $key => $value) {
        $output[call_user_func($fn, $value, $key, $arrayLike) ? "true" : "false"][] = [$key, $value];
    }
    return $output;
});
Beispiel #16
0
<?php

namespace PHPixme;

/**
 * gte, short for greater than or equal to, a stand in for >=
 * @sig ($lhs)->($rhs)-> boolean $z
 * @param mixed $lhs
 * @param mixed $rhs
 * @return boolean|\Closure
 */
function gte($lhs = null, $rhs = null)
{
    return call_user_func_array(__PRIVATE__::$instance[gte], func_get_args());
}
const gte = __NAMESPACE__ . '\\gte';
__PRIVATE__::$instance[gte] = __PRIVATE__::curryExactly2(function ($lhs, $rhs) {
    return $lhs > $rhs;
});
Beispiel #17
0
<?php

namespace PHPixme;

/**
 * Before decorator
 * Wraps a Closure around a callable, running the decorating callable with the same arguments
 * before executing and returning the value of the decorated function
 * @param Callable $decorator
 * @param Callable $fn
 * @return \Closure
 * @sig Callable (*->) -> Callable (*->x) -> Closure (*->x)
 */
function before($decorator = null, $fn = null)
{
    return call_user_func_array(__PRIVATE__::$instance[before], func_get_args());
}
const before = __NAMESPACE__ . '\\before';
__PRIVATE__::$instance[before] = __PRIVATE__::curryExactly2(function ($decorator, $fn) {
    __CONTRACT__::argIsACallable($decorator);
    __CONTRACT__::argIsACallable($fn, 1);
    return function () use($decorator, $fn) {
        $args = func_get_args();
        call_user_func_array($decorator, $args);
        return call_user_func_array($fn, $args);
    };
});
Beispiel #18
0
<?php

namespace PHPixme;

/**
 * shiftL, or shift left, a stand in for <<
 * @param int|float $lhs
 * @param int $rhs
 * @return int|\Closure
 */
function shiftL($lhs = null, $rhs = null)
{
    return call_user_func_array(__PRIVATE__::$instance[shiftL], func_get_args());
}
const shiftL = __NAMESPACE__ . '\\shiftL';
__PRIVATE__::$instance[shiftL] = __PRIVATE__::curryExactly2(function ($lhs, $rhs) {
    return $lhs << $rhs;
});
Beispiel #19
0
<?php

namespace PHPixme;

/**
 * nid, short for not the identity, or not strictly equals, a stand in for !==
 * @sig ($lhs)->($rhs)-> boolean $z
 * @param mixed $lhs
 * @param mixed $rhs
 * @return boolean|\Closure
 */
function nid($lhs = null, $rhs = null)
{
    return call_user_func_array(__PRIVATE__::$instance[nid], func_get_args());
}
const nid = __NAMESPACE__ . '\\nid';
__PRIVATE__::$instance[nid] = __PRIVATE__::curryExactly2(function ($lhs, $rhs) {
    return $lhs !== $rhs;
});