Se então, senão
Você saberia calcular o maior de dois números \(a\) e \(b\) sem usar um teste do tipo se então senão? É bem interessante; assuma \(M\) maior e \(m\) menor entre \(a\) e \(b\).
Em outras palavras, o maior entre dois números \(a\) e \(b\) é igual à média dos números \(a\) e \(b\), mais a metade da diferença entre \(a\) e \(b\). Logo, em Haskell, temos
maior x y = (x + y + (abs (x - y))) / 2
Estou certo de que você concordará que calcular o maior entre dois números deveria ser muito mais simples que isso, especialmente porquê naquele abs
provavelmente há um se-então-senão
escondido.
Mas como fazê-lo em Haskell, isto é, como testar uma condição sobre os valores para decidir a forma correta de computar o resultado?
Usando uma expressão de seleção, isto é, if ... then ... else ...
Esta estrutura tem a seguinte sintaxe, em que a definição True é usada caso a condição avalie para True e condição False é usada caso contrário.
if <condição> then <definição True> else <definição False>
Por exemplo, veja podemos calcular o maior de dois números com a seguinte definição.
maior x y = if x > y then x
else y
Observe que, diferentemente de outras linguagens em que se pode usar o if
para decidir entre fazer ou não uma computação, o if
do Haskell serve para decidir entre duas computações. Isto é, o if
deve sempre ser seguido do then
e do else
.
Observe também que o if
pode estar em qualquer parte da expressão, porquê este construto é também uma expressão.
Por exemplo, imagine que queira somar um número inteiro com o valor absoluto de outro número, sem usar o abs
.
somaEstranha x y = x + (if y < 0 then -y else y)
Com esta definição, tanto somaEstranha 1 2
quanto somaEstranha 1 (-2)
resultam em 3. Mas este exemplo é muito estranho, então pensemos em um mais "útil", como determinar se um ano é bissexto.
- Se o ano não é múltiplo de 4, não é bissexto.
- Se é múltiplo de 4 e não é múltiplo de 100, então é bissexto.
- Se é múltiplo de 100 e não é múltiplo de 400, então não é bissexto.
- Se é múltiplo de 400, então é bissexto.
bissexto x = if mod x 4 /= 0
then False
else if mod x 100 /= 0
then True
else if mod x 400 == 0
then True
else False
Aninhar if
assim pode funcionar, mas leva a estruturas complexas e difíceis de serem lidas. Há formas melhores de se lidar com múltiplas possibilidades de computação, como veremos adiante.