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.

M=M+M2=M+m+Mm2=M+m+(Mm)2=M+n+Mm2=a+b+ab2=a+b2+ab2

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.

abs(a,b)={a,if abb,otherwise

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.