Your example implementation shows why this isn't really necessary. Moreover it doesn't compose well. Consider:
map
|> Enum.filter(fn {k, v} -> key_filter(k) && value_filter(v) end)
|> Map.new
vs
map
|> Map.filter_keys(key_filter)
|> Map.filter_values(value_filter)
In the latter it starts as a map, becomes a list, becomes a map again, then becomes a list, then becomes a map again.
There are a common set of operations which make sense for both lists, maps, streams, and other user made datastructures. Those common operations have been extracted into the Enum module based on the Enumerable protocol, and thats where they belong.