public static function types(callable $f)
    {
        $ref = self::getReflection($f);

        $docs = $ref->getDocComment();
        $proto = $ref->getParameters();

        preg_match_all('/@param\s+(?P<type>.*?)\s+\$(?P<name>.*?)\s+/', $docs, $docs, PREG_SET_ORDER);

        $params = array();
        foreach ($proto as $p) {
            $name = $p->getName();
            $type = null;
            foreach ($docs as $k => $d) {
                if ($d['name'] === $name) {
                    $type = $d['type'];
                    unset($docs[$k]);
                    break;
                }
            }
            if (is_null($type)) {
                throw new MissingTypeAnnotationException("Cannot determine type for $name.");
            }
            if (count(explode('|', $type)) > 1) {
                throw new AmbiguousTypeAnnotationException("Ambiguous type for $name : $type");
            }
            $params[$name] = $type;
        }

        return $params;
    }