let rec filter predicate = function
  | Dir(path, name, st, attr, entries) ->
      if predicate path name attr then
        Dir(path, name, st, attr, lazy (List.map (filter predicate) !*entries))
      else
        Nothing
  | File(path, name, _, attr) as f ->
      if predicate path name attr then
        f
      else
        Nothing
  | Nothing -> Nothing
  | Error _ as e -> e