I have a list of mix of integer and atom. I want to match the head of the list with atom otherwise integer.
lst = [1,2,3,4,5,6, :eoe, 7,8,9,10,11,12. :eoe]
I initially tried this way:
defmodule Test do
def test(lst) do
helper(lst, 0, 0, 1)
end
def helper([], _p, total, e) do
IO.puts "#{e} #{t}"
end
def helper([:eoe , t], _p, total, e) do # <--- This function never called even though head is at some point :eoe
IO.puts "#{e} #{total}"
helper(t, "", 0, elf 1)
end
def helper([h | t], p, total, e) do
h
|> is_atom()
|> IO.inspect()
helper(t, h, total h, e)
end
end
then added guards to explicitly narrow down pattern matching
...
def helper([:eoe = head , t], _p, total, e) when is_atom(head) do
...
def helper([h | t], p, total, e) when is_integer(h) do
...
def helper([:eoe = h , t], _p, total, e) when is_atom(h) do
this function does't get called. It always matches def helper([h | t], p, total, e) when is_integer(h) do
this one. I even placed the former one before latter one. I would expect it be matched against :eoe
CodePudding user response:
To match the head one should use the [h | t]
notation. [h, t]
would match the list of two elements.
- def helper([:eoe = h, t]
def helper([:eoe = h | t]
Also, when is_atom(h)
guard is redundant, once you pattern-match directly on the atom. That said, any of the following would do.
def helper([:eoe | t], _p, total, e) do
def helper([h | t], _p, total, e) when h == :eoe do
def helper([h | t], _p, total, e) when h in [:eoe] do
def helper([h | t], _p, total, e) when is_atom(h) do # match any atom