Como usar o Módulo Tuple em Elixir?

Originalmente publicado em https://dev.to/elixir_utfpr/como-usar-o-modulo-tuple-em-elixir-4h2f

Todos que conhecem Elixir devem conhecer a tupla, uma estrutura de dados que permite você juntar valores de diferentes tipos, sejam estes valores de tipos básicos ou não básicos.

Para criar uma tupla, basta abrir uma chave “{“, listar os valores separados por vírgulas, e fechar a chave “}”.

Exemplos:

{"Adolfo", "UTFPR", 2008}
{:idade, 25, :peso, 60.5}
{true, [:p, :implies, :q]}

Não gosto muito da definição da Elixir School nem da definição do site da linguagem, então vou dar a definição do Dave Thomas em Programming Elixir: tuplas são coleções ordenadas de valores. Ele reforça que “como todas as estruturas de dados em Elixir, uma vez criada uma tupla não pode ser modificada”.

Qual é a forma mais comum de obter valores de tuplas? Fazendo casamento de padrões. No exemplo abaixo, se sabemos que a tupla contém quatro valores, dos quais o primeiro e o terceiro são os átomos :idade e :peso, e o segundo e o quarto são a idade e o peso da pessoa, podemos fazer assim para obter idade e peso:

iex> pessoa = {:idade, 25, :peso, 60.5}
{:idade, 25, :peso, 60.5}
iex> {:idade, idade, :peso, peso} = pessoa
{:idade, 25, :peso, 60.5}
iex> idade
25
iex> peso
60.5

OK, então onde entra o módulo Tuple e o que podemos fazer com ele?
Segundo a documentação, no módulo Tuple você tem “Funções para trabalhar com tuplas.” Meio óbvio, né?

Eu confesso que nem sabia da existência deste módulo até alguém perguntar por tuplas no Discord da Groxio Learning:

A própria documentação do módulo avisa: “As funções neste módulo que adicionam e removem elementos de tuplas raramente são usadas na prática, pois geralmente implicam que tuplas estão sendo usadas como coleções.”

O módulo Tuple (na versão 1.11.1 de Elixir) tem apenas 5 funções:

Abaixo algumas interações na iex do Elixir usando as funções acima:

iex> pessoa = {:idade, 25, :peso, 60.5}
{:idade, 25, :peso, 60.5}
iex> Tuple.append(pessoa, "João")
{:idade, 25, :peso, 60.5, "João"}
iex> Tuple.delete_at(pessoa, 3)
{:idade, 25, :peso}
iex> Tuple.duplicate(:elixir, 5)
{:elixir, :elixir, :elixir, :elixir, :elixir}
iex> Tuple.insert_at(pessoa, 4, "João")
{:idade, 25, :peso, 60.5, "João"}
iex> Tuple.insert_at(pessoa, 3, "João")
{:idade, 25, :peso, "João", 60.5}
iex> Tuple.to_list(pessoa)
[:idade, 25, :peso, 60.5]

Como você pode ver acima, o primeiro elemento de uma tupla tem índice 0.

Vocês também podem usar, como tuplas, três funções que não são do módulo Tuple:

Exemplos:

iex> pessoa = {:idade, 25, :peso, 60.5}
{:idade, 25, :peso, 60.5}
iex> tuple_size(pessoa)
4
iex> elem(pessoa,1)
25
iex> elem(pessoa,0)
:idade
iex> put_elem(pessoa,0, "oi")
{"oi", 25, :peso, 60.5}

Na página da linguagem há uma discussão um pouco mais avançada sobre a diferença entre listas e tuplas.

Portanto, o conselho é: usem tuplas mas evitem usar o módulo Tuple.

Sou Professor da UTFPR. Aqui publico textos em português. Texto em inglês estão em https://medium.com/@adolfont Twitter: https://twitter.com/adolfont.

Sou Professor da UTFPR. Aqui publico textos em português. Texto em inglês estão em https://medium.com/@adolfont Twitter: https://twitter.com/adolfont.