{ lib }: root: patterns: f: lib.listToAttrs ( lib.concatMap ( dirent: let fname = dirent.name; typ = dirent.value; fpath = root + "/${fname}"; doMatch = pat: let match = pat fpath fname typ; value = f match fpath typ; in if match == null then [ ] else [ (lib.nameValuePair match value) ]; in (lib.take 1 (lib.concatMap (doMatch) patterns)) ) (lib.attrsToList (builtins.readDir root)) )