An alternative to reduce_while when validating until the first error?

I have a bunch of map validation functions that are similar to

defp validate(map, :keys, module) do
  allowed_keys = module.__fields__(:keys, :set)
  Enum.reduce_while(map, :ok, fn ({k, v}, :ok) ->                        
    case allowed_keys.member?(k) do
      true -> {:cont, :ok}
      false -> {:halt, {:error, {:key, k, :unexpected }}}
    end
  end)
end

reduce_while does the job but it’s not a perfect fit when we merely want to validate until the first error. What would be a better way to write this? Thanks!

If you don’t need to accumulate values, you could use Enum.find:

case Enum.find(map, fn {key, _} -> not allowed_keys.member?(key) end) do
  nil -> :ok
  {key, _} -> {:error, {:key, key, :unexpected}}
end
3 Likes

Cool, thank you!