Exercícios Práticos: Programação funcional com Haskell
Preparação
Para este exercício você vai precisar do GHC (Glasgow Haskell Compiler), que é composto por um compilador e um interpretador para Haskell. Em http://www.haskell.org/ghc/dist/current/dist/ você encontra o GHC para Linux e Windows. O exemplo abaixo mostra como invocar o interpretador do GHC no Linux:
user@host:~$ ghci GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude>
Comandos básicos do GHCi
- :load ou :l: carrega um programa
- :quit ou :q ou Ctrl-D: sai do interpretador
- :type funcao ou :t funcao: mostra o tipo de uma funcao
Tuplas
Tuplas são tipos de dados compostos em Haskell. Ao contrário das listas, as tuplas podem conter dados heterogêneos (de diferentes tipos). Notação: (elem1, elem2, ..., elemN)
Exemplo:
> ("Fulano", 22) -- tupla contendo string e número
Tuplas são convenientes para representar novos tipos de dados. Por exemplo, pode-se usar tuplas (String, Int) para representar pessoas e criar funções que operem sobre esse tipo de dado:
-- Funcao que verifica se a pessoa é maior de idade maiorDeIdade :: (String,Int) -> Bool maiorDeIdade (_,i) = if i >= 18 then True else False
Observação: A função acima usa casamento de padrões para tuplas. Ela poderia ser reescrita usando funções `fst` e `snd` que retornam o primeiro e segundo elementos de uma tupla, respectivamente:
maiorDeIdade :: (String,Int) -> Bool maiorDeIdade p = if snd p >= 18 then True else False
Exercícios com tuplas:
- Usando tuplas (Float,Float) para representar pontos num espaço 2D, crie uma função distPoint que calcule a distância entre 2 pontos, dada pela fórmula abaixo:
Use casamento de padrões nesta função.
- Reescreva a função do exercício anterior, sem usar casamento de padrões (use funções fst e snd).
Tipos
Uma forma de criar novos tipos de dados em Haskell é usando a função type. Por exemplo, podemos criar o tipo Pessoa para tuplas (String,Int) e assim redefinir a função maiorDeIdade:
type Pessoa = (String,Int) maiorDeIdade :: Pessoa -> Bool maiorDeIdade (_,i) = if i >= 18 then True else False
Exercícios:
- Crie um tipo Point para representar um ponto em 2D.
- Reescreva a função distPoint usando o novo tipo.
Funções de Alta Ordem
- Use a função map em uma lista de pessoas (ex: [("Beltrano",10), ("Sicrano",20), ("Fulaninho", 5)]) para verificar se elas são ou não maiores de idade. Faça esse exercício direto no interpretador, depois de carregar um arquivo com as definições do tipo Pessoa e da função maiorDeIdade.
- Use a função map e a função fst para obter os nomes das pessoas na lista [("Beltrano",10), ("Sicrano",20), ("Fulaninho", 5)].
- Obtenha o somatório das idades das pessoas na lista acima, usando as funções map, snd e sum.
IO
- Baixe o programa svg-simple.hs e carregue-o no interpretador. Você consegue entender o que faz este programa?
- Modifique o programa acima para desenhar uma lista de círculos.