public static function run(callable $tryBlock, array $exceptions = [], callable $finallyBlock = null) : TryTo
    {
        try {
            return Success::of(Functions::call($tryBlock));
        } catch (Exception $e) {
            if (count($exceptions) === 0) {
                return Failure::of($e);
            }
            $error = FluentIterable::of($exceptions)
                ->filter(Predicates::assignableFrom(get_class($e)))
                ->first();
            if ($error->isPresent()) {
                return Failure::of($e);
            }
            throw $e;
        } finally {
            if ($finallyBlock !== null) {
                Functions::call($finallyBlock);
            }
        }
    }