What is the most elegant way to do the following?
I have multiple functions (strategies) that I want to invoke, in order. Each can return {:ok, result}
or {:error, :not_found}
. If the first strategy fails the second one should be tried and so on. The return value should be that of the first succeeding strategy, or the return value (error tuple) of the last strategy if none succeed.
To give some context, I’m trying to locate the contact page on websites. First strategy is to try /contact
, then /contact.html
, then to look on the homepage for <a href="...">Contact</a>
, and so on.
My current solution is something like this:
case find_contact_page_url1(website_url) do
{:ok, contact_page_url} ->
{:ok, contact_page_url}
{:error, :not_found} ->
case find_contact_page_url2(website_url) do
{:ok, contact_page_url} ->
{:ok, contact_page_url}
{:error, :not_found} ->
find_contact_page_url3(website_url)
end
end
At first I thought this can be done using with
but it does exactly the opposite (invoke multiple functions as long as each one matches).