static function prototype(callable $callable) {
        /** @var \ReflectionMethod|\ReflectionFunction  $prototype */
        
        if(\is_array($callable)) {
            $prototype = new \ReflectionMethod($callable[0], $callable[1]);
        } else {
            $prototype = new \ReflectionFunction($callable);
        }
        
        $signature = '';
        
        /** @var \ReflectionParameter  $param */
        foreach($prototype->getParameters() as $param) {
            $type = $param->getType();
            $signature .= ($type->allowsNull() ? '?' : '').$type->getName().($param->isOptional() ? '?' : '').',';
        }
        
        $signature = \substr($signature, 0, -1);
        
        $return = $prototype->getReturnType();
        if($return !== null) {
            $signature .= '='.($return->allowsNull() ? '?' : '').$return->getName();
        }
        
        if(empty($signature)) {
            throw new \InvalidArgumentException('Given callable has no signature to build');
        }
        
        return $signature;
    }