VictorCacciari 42 Denunciar post Postado Janeiro 27, 2010 Aula 04 - Variáveis e mais recursividade Olá Pessoal, desculpem a demora, mas estamos de volta! Hoje já vamos começar a fazer coisas mais úteis para o 'projeto' final. Variáveis Em Haskell, podemos trabalhar com uma espécie de variáveis, a forma mais fácil de explicar é com exemplos. f :: Int -> Int -> Int f a b = let c = a + b in c*2 Ou f :: Int -> Int -> Int f a b = c * 2 where c = a + b Também é válido. A diferença entre o 'let' e o 'where' é o escopo. O let é mais restrito, e as coisas ficam apenas visíveis naquele ramo, já o where fornece informação para todas as condições. Por exemplo (nota: '++' concatena listas): g :: Int -> [Int] -> Bool g a l | a == 0 = aux l | otherwise = aux (l ++ [0]) where aux :: [a] -> Bool aux n = faz_qualquer_coisa_com_n A função aux está visível tanto para o sub-ramo onde a é zero, quanto para o outro. A declaração com lets não permite isso. Outro recurso interessante é que é possível fazer pattern matching com 'let's e 'where's Por exemplo, uma possível definição para a função unzip, que pega numa lista com pares e retorna um par de listas: unzip :: [(a, B)] -> ([a], [b]) unzip [] = [] // caso elementar unzip ((e1, e2):t) = let (l1, l2) = unzip t // Nós vamos primeiro fazer unzip no resto da lista in (e1:l1, e2:l2) //E apenas quando toda a lista ja estiver pronta, colocamos os elementos nas listas corretas. Outro exemplo, a função splitAt, que divide uma lista numa dada posição e retorna um par com duas listas: splitAt :: Int -> [a] -> ([a], [a]) splitAt 0 a = ([], a) //dividir a lista na posição zero splitAt n (h:t) = let (l1, l2) = splitAt (n-1) t in (h:l1, l2) EXERCÍCIOS: //Defina a função div, que divide dois números inteiros, usando recursividade div :: Int -> Int -> Int //Defina a função mod, que retorna o modulo de dois números inteiros, usando recursividade mod :: Int -> Int -> Int //A função divMod pode ser definida da seguinte forma: divMod :: Int -> Int -> (Int, Int) divMod a b = (div a b, mod a B) //Apresente uma definição recursiva para a função divMod //defina a função insere, que recebe um inteiro e insere-o numa lista ordenada, mantendo-a ordenada. insere :: Int -> [Int] -> [Int] //defina a função merge, que recebe duas listas ordenadas e retorna uma lista ordenada, dica: use a função insere merge :: [Int] -> [Int] -> [Int] //defina uma função ordena, que ordena uma lista ordena :: [Int] -> [Int] //defina a função unzip3, que faz o mesmo que a função unzip, mas com ternos unzip3 :: [(a, b, c)] -> ([a], [b], [c]) Pessoal, é importante entender muito bem esses conceitos, para partirmos para estruturas de dados e tipos abstratos de dados. Aconselho que façam os exercícios e postem dúvidas, busquem mais exercícios na internet para resolvê-los. ATENÇÃO: as funções div, mod, divMod e unzip3 já estão definidas no Haskell, utilizem outros nomes. Compartilhar este post Link para o post Compartilhar em outros sites