martes, 6 de junio de 2017

Empezando con Elixir 4

Pattern Matching

Pattern Matching es una parte importante y poderosa de elixir. Esto permite machear valores simples, estructura de datos e incluso funciones. Veamos como trabaja:

El operador Match
En elixir el operador = es un operador de macheo. Elixir espera que coincida los valores de la mano izquierda con los valores de la mano derecha. Si coinciden, devuelve el valor de la ecuación. De lo contrario, se produce un error. Vamos a ver un ejemplo:

iex> x = 1
1

Ahora vamos a probar el macheo:

iex> 1 = x
1
iex> 2 = x
** (MatchError) no match of right hand side value: 1

Ahora veamos ejemplos con varias estructuras:

# Lists
iex> list = [1, 2, 3]
iex> [1, 2, 3] = list
[1, 2, 3]
iex> [] = list
** (MatchError) no match of right hand side value: [1, 2, 3]

iex> [1 | tail] = list
[1, 2, 3]
iex> tail
[2, 3]
iex> [2 | _] = list
** (MatchError) no match of right hand side value: [1, 2, 3]

# Tuples
iex> {:ok, value} = {:ok, "Successful!"}
{:ok, "Successful!"}
iex> value
"Successful!"
iex> {:ok, value} = {:error}
** (MatchError) no match of right hand side value: {:error}

Operador Pin

El operador de = realiza la asignación cuando el lado izquierdo de la coincidencia incluye una variable. En algunos casos, este comportamiento no es deseable. Para estas situaciones tenemos el operador pin: ^.

Veamos un ejemplo:

iex> x = 1
1
iex> ^x = 2
** (MatchError) no match of right hand side value: 2
iex> {x, ^x} = {2, 1}
{2, 1}
iex> x
2


iex> key = "hello"
"hello"
iex> %{^key => value} = %{"hello" => "world"}
%{"hello" => "world"}
iex> value
"world"
iex> %{^key => value} = %{:hello => "world"}
** (MatchError) no match of right hand side value: %{hello: "world"}

En Elixir 1.2 se agrega soporte para que el pin funcione en mapas o funciones.

iex> key = "hello"
"hello"
iex> %{^key => value} = %{"hello" => "world"}
%{"hello" => "world"}
iex> value
"world"
iex> %{^key => value} = %{:hello => "world"}
** (MatchError) no match of right hand side value: %{hello: "world"}

Veamos un ejemplo con funciones:

iex> greeting = "Hello"
"Hello"
iex> greet = fn
...>   (^greeting, name) -> "Hi #{name}"
...>   (greeting, name) -> "#{greeting}, #{name}"
...> end
#Function<12.54118792/2 in :erl_eval.expr/5>
iex> greet.("Hello", "Sean")
"Hi Sean"
iex> greet.("Mornin'", "Sean")
"Mornin', Sean"

Dejo link: https://elixirschool.com/lessons/basics/pattern-matching/