# Haskell/Casamento de padrões

* Casamento de padrões
* Básico
* Recursividade
* Listas II (listas infinitas, map)
* Listas III (folds, compreensão)
* Declaração de tipos
* Lambdas e operadores
* Casamento de padrões
* Estruturas de controle: case
* Funções de alta ordem
* Usando o GHCi
Nos módulos passados apresentamos um pouco sobre casamento de padrões. Agora que já estamos mais familizariados com Haskell, é hora de entendermos esta ferramenta. Vamos começar com um resumo desta parte, o qual será expandido ao longo deste capítulo:
Quando usamos casamento de padrões, casamos valores com padrões e, se quisermos, vinculamos variáveis padrão casado.

## Entendendo o mecanismo

Encontramos casamento de padrões em todos os lugares. Considere a função map:
Num primeiro instante, identificamos quatro padrões envolvidos, sendo dois por expressão:
* _ é um padrão que casa com qualquer argumento, independente de seu valor e sem vincular nenhuma variável. É como um padrão coringa que ignora qualquer entrada.
* é um valor e representa um padrão que casa com listas vazias. Nenhuma variável é vinculada neste caso.
* f é um padrão que pode ser casado com qualquer argumento e vincula a variável f ao argumento casado.
* (x:xs) é um padrão que casa com listas não-vazias, a quais possuem uma cabeça, que é vinculada à variável x, e uma cauda, vinculada a xs.
No caso (x:xs), as variáveis podem ser considerada como sub-padrões usados para casar com as duas partes de uma lista. Bem como f, x e xs casam com qualquer entrada, mas vale notar que se x for do tipo a, então xs será do tipo [a]. Isso implica que xs pode ser vinculada a uma lista vazia cujo tipo é [a] e, portanto, o (x:xs) pode ser casado com listas contendo um único elemento.
Então, podemos dizer que casamento de padrões nos permite:
* Reconhecer valores. Quando usamos map e o segundo argumento é casado com, a primeira definição de map é usada em vez da segunda.
* Vincular variáveis aos valores reconhecidos. Neste caso, as variáveis f, x e xs são vinculadas quando a segunda definição é usada e podemos, então, usar estes nomes do lado direito da expressão para nos referirmos aos argumentos de map. Mas como podemos ver na primeira definição, onde usamos e _, vincular variáveis não é essencial.
* Dividir valores em partes menores. É exatamente isso que (x:xs) faz, pois vincula nomes às duas partes (cabeça e cauda) de uma lista não-vazia.

## Envolvendo construtores de tipo

Mesmo com a análise mais detalhada que acabamos de fazer, ainda parece um passe de mágica o fato de podermos desconstruir uma lista que foi unida usando a função (:). Talvez você queira tentar fazer algo similar com uma lista unida por (++):
Você pode testar no GHCi, mas ele retornará um erro. A função (++) não pode ser usada em casamento de padrões. Na verdade, a maioria das funções que não podem ser usadas.
Mas então, quais funções podem ser usadas em casmento de padrões? A resposta é simples: construtores de tipos. Por exemplo, considere o tipo:
Temos que Bar e Baz são construtores do tipo Foo. Sendo assim, podemos usá-los em padrões de argumentos que devem ser do tipo Foo, por exemplo:
Relembrando o capítulo passado, é exatamente assim que mostrarData e mostrarAniversario funcionam:
O argumento (Data a m d) casa com um tipo de dado Data, que é criado usando o construtor Data, e vincula as variáveis a, m e d aos valores contidos em Data.

### Por que a função (:) funciona em listas?

Isso acontece porque (:) é um operador de construção, assim como Data, Bar e Baz. Listas são definidas usando data:
Assim, uma lista vazia, além de ser um valor por si só, também é um construtor de tipo. A função (:) também é construtora de tipo. Deste modo, a restrição de que apenas funções construtoras de tipo podem ser usadas em casamento de padrões é satisfeita.
A forma correta de implementar eliminarTres é convertendo a lista para a notação de cons:
O padrão (_:_:_:xs) casa com qualquer lista de pelo menos três elementos. O segundo retorna uma lista vazia caso a entrada tenha dois elementos ou menos.

### Construtores de n-uplas

Uma analogia semelhante é válida para n-uplas. O construtor deste tipo é o operador vírgula: para duplas, usa-se uma vírgula, (,); para triplas, duas, (,,); e assim por diante. Por serem construtores, podemos usar casamento de padrões:
Bem como cons, podemos usar (,) como uma função, o que pode ser útil em algumas ocasiões:
Entretanto, o uso de parênteses é obrigatório no modo infixo: 5, 3 é inválido, enquanto (5, 3) é válido.

## Casando valores literais

Como já vimos antes, podemos casar padrões com valores literais. Por exemplo:
Neste caso, a definição de f esta casando seus argumentos com valores pré-definidos (0, 1 e 2), mais um caso geral (ou de exceção) (_). Em geral, valores específicos podem ser casados individualmente bem como juntos a construtores. Veja:
A função g retorna False se a entrada for uma lista de um único elemento que seja igual a 0; True se a lista tiver mais que um elemento e a cabeça for igual 0; e False para todos os outros casos. Listas com tamanhos fixos também podem ser usadas para definir um padrão, como [a,b,c], [1,2,3] ou "abc".
Devemos saber, entretanto, que o uso de nomes de variáveis tem contexto limitado. Por exemplo, não podemos definir uma variável fora da função e usá-la no casamento de padrões:
O compilador pode aceitar a definição, mas ele não casará o argumento k com a variável global k. Podemos, entretanto, comparar os dois valores dentro da função, desde que eles possuam nomes diferentes:
* Exercícios
* Teste a primeira versão de h no GHCi. O que acontece? Dê um exemplo em que ela retorne False.

## Mais sintaxe
### Nomeando padrões com @

Em certos momentos, quando casamos algum sub-padrão, talvez ainda seja útil vincular um nome para o argumento todo. A sintaxe @ nos permite fazer justamente isso: usando var@padrao, definimos o nome var para nos referimos ao argumento de entrada e padrao para definir o padrão de casamento.
Por exemplo:
Aqui usamos lista para nos referirmos ao argumento de entrada de primeiroEsomar e passá-lo para a função sum. No segundo padrão, além disso, temos x casado com a cabeça de lista, e xs com sua cauda.

### Casamento com registros

Suponha o seguinte tipo definido usando a sintaxe de registros:
Podemos casar padrões com registros usando apenas os construtores (Bar ou Baz), ou também os campos:
Em f, comparamos apenas os construtores. Para casar apenas os construtores de um registro, deve-se acrescenter um par de chaves à esquerda, como em Baz. Já em g, os padrões envolvem construres e valores específicos:
* No primeiro caso usamos apenas o construtor Bar.
* O segundo só é casado a entrada usar o construtor Baz e se o campo nome tiver valor "João".
* O terceiro casa com qualquer valor que use Baz, sendo que ele ainda vincula a variável n ao valor do campo numero.

## Onde aplicar

Onde podemos usar casamento de padrões? A resposta curta é onde quer que possamos vincular variáveis, podemos usar casamento de padrões. Com base no que já sabemos até agora de Haskell, vejamos onde podemos aplicar casamento de padrões.

### Definição de funções

O uso mais óbvio é do lado esquerdo da definição de uma função, e foi o que vimos até o momento. Para exemplos, basta rever este capítulo.

### Expressões let e cláusulas where

Tanto let quando where são métodos distintos para vincular variáveis de forma local, sem envoler os argumentos de entrada de uma função, por exemplo. Veja:
Tanto y quando y' retornam o mesmo resultado. Em ambos os casos vinculamos a variável x ao primeiro elemento de map (*2) [1..3].

### Expressões lambdas

Também podemos usar casamento de padrões em funções anônimas:
É claro, entretanto, que a sintaxe das expressões lambdas permitem apenas um padrão por argumento da expressão.

### Compressão de listas

Podemo usar casamento de padrões depois de | numa compressão de lista. Na verdade, é um caso bastante útil para algumas expressões complexas, mas vejamos com simples n-uplas:

### Blocos do

Dentro de blocos do como os que usamos em Entradas e saídas simples, podemos usar casamento de padrões do lado esquerdo de vinculações <-:
Além disso, ainda podemos usar casamento de padrões dentro expressões let situadas dentro de do da mesma forma que expressões let comuns.