# Haskell/Verdadeiro ou falso

* Verdadeiro ou falso
* Introdução
* Primeiro passo
* Variáveis e funções
* Verdadeiro ou falso
* Tipos básicos
* Listas e n-uplas
* Tipos básicos II
* Casamento de padrões, if e let
* Composição de funções
* Entradas e saídas simples

## Igualdade e outras comparaçãoes

No capítulo usamos sinais de igualdade para definir variáveis e funções em Haskell desta forma:
Isso significa que durante a avaliação do programa, todas as ocorrências de r são substituídas por 5 dentro do mesmo escopo. De modo similar, ao avaliar
todas os ocorrências de f seguidas de um número (o argumento de f), são substituídas por tal valor mais três.
Na Matemática, o sinal de igualdade é usado de forma diferente. Considere o seguinte problema:
* Exercícios
* Resolva o seguinte problema: $x+3=5$.
Neste caso, o problema não representar $5$ como sendo $x+3$ ou vice-versa. Na verdade, temos uma proposição de que um número $x$, quando somado a 3, resulta em 5. Resolver a equação significa achar qual valor de $x$, se é que existe um, torna a proposição verdadeira. Neste exemplo simples, uma simples manipulação algébrica nos mostra que $x=2$, isto é, $2$ é o número que satisfaz a proposição, pois $2+3=5$.
Comparar valores para verificar se são iguais é algo bastante útil para a programação. Na verdade, é algum bastante elementar e necessário. Em Haskell, tais testes se parecem bastante com um equação. Entretanto, já que o sinal de igual já está sendo usado para definir alguma coisa, Haskell usa um sinal duplo de igualdade, ==, para fazer comparações. Veja:
Aqui, GHCi retorna True (verdadeiro, em inglês) porque $2+3$ é igual a $5$. E se a equação não for verdadeira?
O resultado é False (falso, em inglês). Agora vamos usar a função f definimos no começo deste capítulo:
Como esperado. Já que f 2 é avaliado como sendo 2 + 3, que resulta em 5, só poderíamos esperar que 5 == 5 retornasse True.
Nós também podemos comparar dois valores numéricos para saber qual é maior. Haskell possui vários operadores para esses testes: < para menor que; >, maior que; <=, menor que ou igual a; e >=, maior que ou igual a. Esses testes funcionam exatamente como ==, igual a. Por exemplo, poderíamos usar < juntamente com a função area do capítulo anterior para saber se um círculo com um certo raio tem área menor que um outro valor.

## Valores booleanos

O que acontece quando GHCi tem que determinar se essas comparações são verdadeiras ou falsas? Considere um caso diferente. Se entrarmos com uma expressão aritmética no GHCi, ela é avaliada, e o resultado numérico aparece na tela:
Se substituirmos, na comparação, o valor final da expressão aritmética, algo parecido acontece:
Enquanto o "4" retornado primeiro representa a contagem de alguma coisa, o "Verdadeiro" é um valor que representa a verdade de uma certa proposição. Tais valores são conhecidos como booleanos. Naturalmente, apenas dois valores são possíveis, os quais já nos foram apresentados: True e False.

## Introdução a tipos de dados

True e False são valores reais, não apenas uma analogia. Em Haskell, valores booleanos tem o mesmo status que valores numéricos, e podemos manipulá-los de formas semelhantes. Um exemplo trivial:
True é, de fato, igual a True, and True não é igual a False. Agora responda: é possível dizer se 2 é igual a True?
Temos um erro no compilador. Na verdade, a pergunta original sequer faze sentido. Não se pode comparar um número com algo que não é um número, ou um booleano com algo não-booleano. Haskell possui essa noção incorporada em si, e a mensagem de erro acima, apesar de longa e um pouco intimidadora, diz exatamente isso: há um número (Num) do lado esquerdo de ==, então esperava-se um número do lado direito também; contudo, um booleano (Bool) não é um número, então o teste de igualdade falha.
Fica claro, então, que valores são separados em tipo, e que esses tipos definem os limites do que podemos ou não fazer com tais valores. True e False são valores do tipo Bool. Já o 2 é um caso um pouco mais complicado, porque existem vários tipos de números na computação, bem como na matemática (apesar de não serem equivalentes). Mas no fim, ainda é um dado Num. De forma geral, essa característica de limitação é de grande valor, porque podemos usar isso a nosso favor para controlar o comportamento dos nossos programas, criando regras que impedem o uso do programa com tipos que não fazem sentido, o que garante a funcionamento do correto do que desenvolver. Voltaremos a este tópico sobre tipos mais tarde, pois eles são uma parte importante da linguagem Haskell.

## Operadores infixos

Um teste de igualdade, como 2 == 2 , também é uma expressão, bem como uma operação aritmética também o é, como 2 + 2. Ambos os casos são avaliados basicamente da mesma maneira. Quando digitamos 2 == 2 numa sessão do GHCi, ele "responde" com True, pois simplesmente avaliou a expressão. Na verdade, o operador == é uma função de dois argumentos (o lado direito e o lado esquerdo da igualdade). Só que seu uso é diferente: Haskell permite que funções de dois argumentos sejam escritas como operadores infixos, ou seja, que sejam escritas entre seus dois argumentos. Quando o nome da função é, na verdade, caracteres não-alfanuméricos (==, por exemplo), usá-las como operadores infixos é a forma mais comum. Se você deseja usá-las da forma padrão, ou seja, como operadores prefixos (com o nome da função antes dos argumentos), elas devem ser cercadas por parênteses. Veja:
É possível converter um booleano em outro também, usando negação. not é a função de negação: converte True para False, e False para True.
Haskell já possui o operador de diferença: /=, não é igual a. Entretanto, poderíamos definí-lo facilmente usando not e ==:
Note que podemos usar a notação de operadores infixos até mesmo na hora de definí-los. Além disso, um operador pode ser definido a partir de qualquer símbolo ASCII.

### Outras operações booleanas

Existem outras operações com booleanos bastante úteis que necessárias: ou e e.
A operação A ou B resulta em verdadeiro se A, ou B, ou ambos forem verdadeiros. Ela é definida como sendo o operador (||) em Haskell:
A operação A e B resulta em verdadeiro se A e B forem verdadeiros. Ela é definida com osendo o operador (&&):

## Guardas

Os programas escritos em Haskell geralmente usam operadores booleanos numa sintaxe bastante conveniente e abreviada. Quando uma mesma lógica é escrita com uma sintaxe diferente, chamamos isso de açúcar sintático. Quer dizer que o código se torna mais "aprazível ao paladar humano". É bom lembra-se deste termo, pois ele aparece bastante nos materiais sobre Haskell.
Um desses "açúcares", é o que chamamos de guardas, e que usa booleanos para facilitar a implementação de função de maneira bem simples. Primeiro, vamos implementar a função de valor absoluto para números reais, também chamada de função modular ou módulo. Sua definição matemática é que: se um número for positivo, seu módulo é ele mesmo; se um número for negativo, seu módulo é seu oposto, ou 0 menos ele mesmo.
${\text{abs}}(x)=|x|={\begin{cases}x,&{\mbox{se }}x\geq 0\\-x,&{\mbox{se }}x<0.\end{cases}}$
Nesta função, a expressão usada para calcular $|x|$ depende do próprio valor de $x$. Se $x\geq 0$ for verdadeiro, então usamos a primeira expressão; se for falso, a segunda. Para expressar esse processo de decisão em Haskell, usamos guardas, sendo que a função ficaria assim:
É interessante ver que o código acima se parece bastante com a definição matemática. Vamos por partes:
* Começamos com uma definição normal de uma função. Primeiro o nome, absoluto, depois definindo a quantidade de argumentos que ela aceita, x.
* Em vez de usar o sinal = e começar a escrever a definição, nós escrevemos duas alternativas de comportamento logo a baixo. São essas alternativas que chamamos de guardas. Deve-se lembrar que a indentação (os espaços em branco antes de |) não são opcionais, e são usados para mostrar que as guardas estão dentro do escopo da definição de absoluto.
* Cada guarda começa com uma barra vertical, |. Depois dela, deve-se escrever uma expressão que resulte num booleano, também chamada de condição booleana ou predicado. Ela é seguida pelo resto da definição, que começa a partir de =. A definição descrita numa guarda só será avaliada se, e somente se o predicato for avaliado como True.
* O case de otherwise é avaliado quando nenhum dos outros casos acima for verdadeiro. Nestes caso, se x não for menor que zero, então ele só pode ser maior que, ou igual a zero. O predicado da última guarda, portanto, poderia ser x >= 0, mas você geralmente vai ver otherwise como um caso para aceitar todas as outras condições não descritas nas guardas anteriores.
Perceba que escrevemos 0 - x em vez de -x. O que acontece é que - não é uma função de um argumento que retorna 0 - x. Na verdade, trata-se de uma abreviação sintática. Mesmo sendo bastante útil, ela geralmente causa conflito quando usada em conjunto com a função (-), que o operador da subtração. Faça um teste você mesmo no GHCi: calcule 3 menos -4, sem usar parênteses. É para evitar este tipo de problema que decidimos escrever de forma explícita 0 - x.

## Guardas e where

Usar where dentro de uma função com guardas é bastante comum. Por exemplo: para saber quantas soluções reais uma equação de segundo grau possui, do tipo $ax^{2}+bx+c=0$, temos que calcular seu discriminante, $\Delta =b^{2}-4ac$. Se ele for maior que zero, há duas raízes reais; se for nulo, há uma; se for menor que zero, nenhuma. Uma função numSolsReais em Haskell para calcular esta quantidade, poderia ser escrita assim:

## Notas

* ↑ Este termo foi escolhido em homenagem ao matemático britânico George Boole.
* ↑ Esta função já está disponível nas bibliotecas padrões de Haskell, chamada de abs. Não há necessidade de reimplementá-la.
* ↑ Na verdade, poderíamos escrever tudo numa linha só, como f x | caso 1 | caso 2, mas é sempre preferível quebrar linhas para facilitar a leitura.