Ahm*_*etK 3 functional-programming list elixir pattern-matching
我有一个整数和原子混合的列表。我想将列表的头部与原子(否则为整数)匹配。
lst = [1,2,3,4,5,6, :eoe, 7,8,9,10,11,12. :eoe]
Run Code Online (Sandbox Code Playgroud)
我最初尝试过这种方式:
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
Run Code Online (Sandbox Code Playgroud)
然后添加防护来显式缩小模式匹配范围
...
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
...
Run Code Online (Sandbox Code Playgroud)
def helper([:eoe = h , t], _p, total, e) when is_atom(h) do该函数不会被调用。它总是与def helper([h | t], p, total, e) when is_integer(h) do这个匹配。我什至把前一项放在后一项之前。我希望它能够匹配:eoe
为了匹配中心词,应该使用[h | t]符号。将匹配两个[h, t]元素的列表。
- def helper([:eoe = h, t]
+ def helper([:eoe = h | t]
Run Code Online (Sandbox Code Playgroud)
此外,when is_atom(h)一旦直接在原子上进行模式匹配,守卫就变得多余了。也就是说,以下任何一项都可以。
- def helper([:eoe = h, t]
+ def helper([:eoe = h | t]
Run Code Online (Sandbox Code Playgroud)