protected static function memoize(Callable $f)
    {
        return function(...$args) use ($f) {
            static $cache;

            if ($cache === null)
                $cache = [];

            $key = serialize($args);

            if (array_key_exists($key, $cache)) {
                return $cache[$key];
            } else {
                $result = call_user_func_array($f, $args);
                $cache[$key] = $result;

                return $result;
            }
        };
    }
protected static function memoize(Callable $f)
    {
        return function(...$args) use ($f) {
            static $cache;

            if ($cache === null)
                $cache = [];

            $key = serialize($args);

            if (array_key_exists($key, $cache)) {
                return $cache[$key];
            } else {
                $result = call_user_func_array($f, $args);
                $cache[$key] = $result;

                return $result;
            }
        };
    }
protected static function memoize ( Callable $ f ) { return function ( ... $ args ) use ( $ f ) { static $ cache ; if ( $ cache === null ) $ cache = [ ] ; $ key = serialize ( $ args ) ; if ( array_key_exists ( $ key , $ cache ) ) { return $ cache [ $ key ] ; } else { $ result = call_user_func_array ( $ f , $ args ) ; $ cache [ $ key ] = $ result ; return $ result ; } } ; }
Memoize a Function

Provided a function $f, return a new function that keeps track of all calls to
$f and caches their responses. Good for functions that have long-running execution times.
Bad for functions that have side effects. But you don't write those now do you?

```
$myFastFunction = $memoize($myBigFunction);

$myFastFunction(1, 2); // Really long wait
$myFastFunction(1, 2); // Instantaneous response
```

@type (* -> *) -> * -> *

@param  Callable $f Function to memoize
@return Callable    Memoized funciton $f
Memoize a Function