Universidade Federal do Espírito Santo Introdução à Programação uma Abordagem Funcional Programação I Prof.ª Claudia Boeres [email protected] CT VII - Sala 34 Departamento de Informática Centro Tecnológico Universidade Federal do Espírito Santo Co-Autoria: Clebson Oliveira Validação de Dados Como sabemos, toda função tem um domínio e um contradomínio. No interpretador do Haskell, quando tentamos avaliar uma instância de uma definição, usando valores fora desse domínio, podemos receber como resposta mensagens nem sempre esclarecedoras; Quando se trata do usuário de nosso programa, este tipo de mensagem é ainda mais indesejável; Os programadores, que descrevem as funções, podem discernir com mais facilidade a natureza dos problemas que ocorrem durante o seu desenvolvimento; O mesmo não se pode esperar de alguém que não tem conhecimento dos elementos internos às descrições das nossas funções. Tipos de Erro Tipicamente os erros são de duas naturezas. Pode ser que o tipo da instância esteja correto, mas nossa definição use alguma função primitiva que não se aplica ao valor da instância: Tipos de Erro Outro tipo de problema ocorre quando o tipo de algum parâmetro da nossa instância não casa com o tipo inferido pelo interpretador. Por exemplo, se usamos um valor do tipo Float para y, obtemos: Caracterização do Problema Desejamos construir uma função que seja uma extensão da função original (fx) e ao mesmo tempo lhe sirva como uma casca de proteção contra as violações de domínio; Projeto da Solução Uma solução geral bastante conveniente é construir um novo contradomínio (NCD) para fx (extensão de f), formado por pares onde o primeiro elemento é do tipo boolean e o segundo do contradomínio de f: NCD(fx) = (boolean, CD(f)) Projeto da Solução Para valores de x no domínio de f, teremos: fx x = (True, f x ) Para os valores de x fora do domínio teremos: fx x = (False, k ) » onde k é um valor qualquer pertencente ao contradomínio de f. Solução fx x y z = if invalido x y z then (False,0) else (True, f x y z) where invalido x y z = ... f x y z = div x y + z Exemplo – Raízes do 2º grau Sabemos que o universo é definido pelos tipos dos três parâmetros (a, b, c), é maior que o domínio da função; Ou seja, a função não está definida para instâncias de a, b e c, onde se verifica a seguinte desigualdade: (b^2) + (4 * a * c) < 0 Exemplo – Raízes do 2º grau Solução 1: re2gx a b c = (not (delta < 0), if delta < 0 then (0,0) else (x1, x2)) where delta = (b ^ 2) - (4 * a * c) x1 = ((-b) + sqrt delta) / (2 * a) x2 = ((-b) - sqrt delta) / (2 * a) Exemplo – Raízes do 2º grau Solução 2: re2gx a b c = if delta < 0 then (False, (0, 0)) else (True, (x1, x2)) where delta = (b ^ 2) - (4 * a * c) x1 = ((-b) + sqrt delta) / (2 * a) x2 = ((-b) - sqrt delta) / (2 * a) Exercício Faça uma função estendida para: f x y = 1/(x+y) fx x y = if invalido x y then (False,0) else (True, f x y) where invalido x y = x+y == 0 f x y = 1/(x+y)