Multiple matches inside reduce

Hi, I have been using Elixir for over a year now and I am doing a course on pragmaticstudio.com. This is my first post here, so be gentle please.

Everything is going fine and I’m not having any problems with the course itself. However, I can’t figure out why this code (included in the course) works at all. And I don’t understand how you are supposed to guess that this works from the documentation or typespec in the Elixir documentation on Enum.

def list_boats(criteria) when is_list(criteria) do
  query = from(b in Boat)

  Enum.reduce(criteria, query, fn
    {:type, ""}, query ->
      query

    {:type, type}, query ->
      from q in query, where: q.type == ^type

    {:prices, [""]}, query ->
      query

    {:prices, prices}, query ->
      from q in query, where: q.price in ^prices
  end)
  |> Repo.all()
end

What is it in Elixir syntax that allows me to have multiple matches after a single fn inside reduce without calling “case” or something to indicated this matching? Can somebody point me towards documentation where this is explained in more detail?

I was also surprised when I saw this for the first time… but it is just an anonymous function with multiple pattern match on the input, as You could also do with Module functions.

defmodule Foo do
  def my_func({:type, ""}, query) do
    #do something
  end
  def my_func({:type, type}, query) do
    #do something else
  end
  ...
end
3 Likes

Thank you :slight_smile: That explains it. Also, your post helped me form the right question for searching the “tubes” so I was able to find this as well.

and this

2 Likes