DEV Community

Daniel Cunha
Daniel Cunha

Posted on

Elixir :: Function, Pattern Matching, default values e when

Em Elixir o pattern matching não está apenas associado com variáveis, mas também com function, podemos utilizar pattern matching em nossas functions, tornando nossas functions específica para cada situação.

Vamos pensar em um jogo de adivinhação, queremos criar um jogo onde podemos adivinhar um número secreto. Com base no número que você recebe como palpite, você pode ter as seguintes saídas:

Condição Respostas
Quando o palpite corresponde ao número secreto Correto
Quando o palpite é um a mais ou um a menos que o número secreto Próximo
Quando o palpite é maior que o número secreto Maior
Quando o palpite for menor que o número secreto Menor
Quando um palpite não é feito Faça um palpite
  • Todas as suposições e números secretos são números inteiros.

O nosso programa tem as seguintes regras:

1. Dê resposta quando o palpite corresponder ao número secreto

Vamos implementar a função compare/2 que recebe dois argumentos, secret_number e guess, que são ambos inteiros.

GuessingGame.compare(5, 5)
# => "Correto"
Enter fullscreen mode Exit fullscreen mode

2. Dê resposta quando o palpite for maior que o número secreto

Nesta situação queremos que a função de comparação responda com Maior.

GuessingGame.compare(5, 8)
# => "Maior"
Enter fullscreen mode Exit fullscreen mode

3. Dê resposta quando o palpite for menor que o número secreto

Nesta situação queremos que a função de comparação responda com Menor.

GuessingGame.compare(5, 2)
# => "Menor"
Enter fullscreen mode Exit fullscreen mode

4. Dê respostas quando o palpite for um a mais ou um a menos que o número secreto

Nessa situação se o valor inserido tiver diferença de 1 seja para maior ou menor queremos que a função de comparação responda com Próximo

GuessingGame.compare(5, 6)
# => "Próximo"
GuessingGame.compare(5, 4)
# => "Próximo"
Enter fullscreen mode Exit fullscreen mode

5. Dê resposta quando não houver palpite

Nessa situação queremos que quando não houve palpite, a função compare responda com Faça um palpite

GuessingGame.compare(5)
# => "Faça um palpite"
GuessingGame.compare(5, :no_guess)
# => "Faça um palpite"
Enter fullscreen mode Exit fullscreen mode

E como podemos resolver este problema? Como falamos anteriormente o Elixir possui um Pattern Matching que também podemos usar em functions. Então, para iniciar nossa implementaçao vamos começar pela parte onde não enviamos palpite.

Inicialmente vamos começar com a function que recebe apenas 1 parâmetro, vamos definir a nossa function para retornar exatamente o que esperamos, que é uma string: “Faça um palpite”

defmodule GuessingGame do
  def compare(secret_number), do: "Faça um palpite"
end
Enter fullscreen mode Exit fullscreen mode

Ok, assim sabemos que ao chamar a function GuessingGame.compare(1) por exemplo, receberemos como retorno a frase "Faça um palpite”

iex(1)> GuessingGame.compare(1)
"Faça um palpite"
Enter fullscreen mode Exit fullscreen mode

Mas também queremos que quando executarmos GuessingGame.compare(1, :no_guess) também receber o mesmo resultado. Para solucionar esse problema vamos precisar utilizar do default value e também do when.

Em Elixir, podemos definir parâmetros em nossas functions com valores defaults e com when podemos escolher que function executar a partir desta condição. Levando isto em consideração, nossa solução final facaria assim:

defmodule GuessingGame do
  def compare(secret_number, guess \\ :no_guess)
  def compare(secret_number, guess) when guess == :no_guess, do: "Faça um palpite"
end
Enter fullscreen mode Exit fullscreen mode

E o resultado seria como este:

iex(1)> GuessingGame.compare(1)
"Faça um palpite"
iex(2)> GuessingGame.compare(1, :no_guess)
"Faça um palpite"
Enter fullscreen mode Exit fullscreen mode

Agora, para atender as demais questões levantadas em nosso sistema, podemos utilizar o when para definir as demais funções e solucionar nosso problema.

defmodule GuessingGame do
  def compare(secret_number, guess \\ :no_guess)
  def compare(secret_number, guess) when guess == :no_guess, do: "Faça um palpite"
  def compare(secret_number, guess) when secret_number == guess, do: "Correto"
  def compare(secret_number, guess) when secret_number - 1 == guess, do: "Próximo"
  def compare(secret_number, guess) when secret_number + 1 == guess, do: "Próximo"
  def compare(secret_number, guess) when  secret_number > guess, do: "Menor"
  def compare(secret_number, guess) when  secret_number < guess, do: "Maior"
end
Enter fullscreen mode Exit fullscreen mode

Top comments (0)