Try to instantiate a Project from the given json object.
        Convert the **type** key to **tpe** and its value to
        Maybe.
        Make sure **root** is a directory, fall back to resolution
        by **tpe/name**.
        Reinsert the root dir into the json dict, filter out all keys
        that aren't contained in Project's fields.
        Try to instantiate.

def from_json(self, json: Map) -> Maybe[Project]:
        ''' Try to instantiate a Project from the given json object.
        Convert the **type** key to **tpe** and its value to
        Maybe.
        Make sure **root** is a directory, fall back to resolution
        by **tpe/name**.
        Reinsert the root dir into the json dict, filter out all keys
        that aren't contained in Project's fields.
        Try to instantiate.
        '''
        root = json.get('root')\
            .map(mkpath)\
            .or_else(
                json.get_all('type', 'name')
                .flat_map2(self.resolver.type_name))
        valid_fields = root\
            .map(lambda a: json ** Map(root=a, tpe=json.get('type')))\
            .map(lambda a: a.at(*Project._pclass_fields))
        return Try(lambda: valid_fields.map(lambda kw: Project(**kw))) | Empty()