defmodule Math do
def sum(a, b) do
a + b
end
end
Math.sum(1, 2)
defmodule Math do
def sum, do: 0
def sum(a), do: a
def sum(a, b), do: a + b
def sum(a, b, c), do: a + b + c
def sum([]), do: 0
def sum([head|tail]), do: head + sum(tail)
end
Math.sum([1, 2, 3, 4])
iex> x = 1
1
iex> 1 = x
1
What's going on 😕?
=
The left-hand side pattern is matched against a right-hand side term. If the matching succeeds, any unbound variables in the pattern become bound. If the matching fails, a run-time error occurs.
In the REPL
iex> a = 1
1
iex> {a, b} = {1, 2}
{1, 2}
iex> [a, b] = [1, 2]
[1, 2]
iex> {a, b, c} = {1, 2}
** (MatchError) no match of right hand side value: {1, 2}
In a function
def f({:a, :b} = tuple), do: IO.puts "All your \#{inspect tuple} are belong to us"
def f([]), do: IO.puts "Empty"
def f(n), do: IO.puts "Inspecting \#{inspect n}"
f([])
#=> "Empty"
f({:a, :b})
#=> "All your {:a, :b} are belong to us"
f({:a, :b, :c})
#=> "Inspecting {:a, :b, :c}"
Let's write an implementation of the Fibonacci sequence
f n = fn-1 + fn-2
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144
function fib(n) {
if (n <= 1) {
return n;
} else {
return fib(n-1) + fib(n-2);
}
}
defmodule Math do
def fib(0), do: 0
def fib(1), do: 1
def fib(n), do: fib(n-2) + fib(n-1)
end
How can we handle < 0 and arguments that are not a number?
defmodule Math do
def fib(n) when not is_number(n), do: raise(ArgumentError, message: "not a number")
def fib(n) when n < 0, do: 0
def fib(0), do: 0
def fib(1), do: 1
def fib(n), do: fib(n-2) + fib(n-1)
end
From binary pattern matching in elixir
defmodule Expng do
defstruct [:width, :height, :bit_depth, :color_type, :compression, :filter, :interlace, :chunks]
def png_parse(<<
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
_length :: size(32),
"IHDR",
width :: size(32),
height :: size(32),
bit_depth,
color_type,
compression_method,
filter_method,
interlace_method,
_crc :: size(32),
chunks :: binary>>) do
png = %Expng{
width: width,
height: height,
bit_depth: bit_depth,
color_type: color_type,
compression: compression_method,
filter: filter_method,
interlace: interlace_method,
chunks: []}
png_parse_chunks(chunks, png)
end
defp png_parse_chunks(<<
length :: size(32),
chunk_type :: size(32),
chunk_data :: binary - size(length),
crc :: size(32),
chunks :: binary>>, png) do
chunk = %{length: length, chunk_type: chunk_type, data: chunk_data, crc: crc}
png = %{png | chunks: [chunk | png.chunks]}
png_parse_chunks(chunks, png)
end
defp png_parse_chunks(<<>>, png) do
%{png | chunks: Enum.reverse(png.chunks)}
end
end