I'm new to Elixir. I want to define a function that accepts only lists, but that can be of any size.
I could define a function that accepts an empty list like this:
def doit(my_list = []) do
IO.puts my_list
end
or just one item, like this:
def doit([first]) do
IO.puts my_list
end
but how do I allow any size list? I know I can accept anything like this:
def doit(my_list) do
IO.puts my_list
end
but wouldn't it be more correct to enforce that it is a list using pattern matching?
Pattern matching allows developers to easily destructure data types such as tuples and lists. As we will see in the following chapters, it is one of the foundations of recursion in Elixir and applies to other types as well, like maps and binaries.
it matches the value on the left hand side with the value on the right hand side. if it matches and if the left hand side includes a variable, it assigns the corresponding value from the right hand side to the variable.
A special feature of languages in the ML family is pattern matching. It allows simple access to the components of complex data structures. A function definition most often corresponds to pattern matching over one of its parameters, allowing the function to be defined by cases.
Overview. We use pattern matching in Haskell to simplify our codes by identifying specific types of expression. We can also use if-else as an alternative to pattern matching. Pattern matching can also be seen as a kind of dynamic polymorphism where, based on the parameter list, different methods can be executed.
You can do it as below with pure pattern match and without the guards:
def any_list(list = [head | tail = []]) do IO.puts("Single Element") end
def any_list(list = [head | tail ]) do IO.puts("Any list") end
def any_list([]) do IO.puts("Empty list") end
As an alternative to pattern matching, you can use the is_list/1 guard function, which does a type check on the function argument:
def doit(my_list) when is_list(my_list) do
# code goes here
end
Or even use it with the size check, if necessary:
def doit(my_list) when is_list(my_list) and length(my_list) > 0 do
# code goes here
end
As far as I know there's no single pattern to match any list. []
will match an empty list and [_ | _]
will match any non-empty list, but there's no way to combine them using a pattern.
You can do this with function guards though, using is_list/1
:
def doit(my_list) when is_list(my_list) do
# my_list is guaranteed to be a list
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With