Este documento apresenta uma introdução à linguagem de programação Haskell. Aborda tópicos como tipos de dados, operadores, funções, recursividade, pattern matching, guards e listas. Haskell é uma linguagem funcional pura com variáveis imutáveis que permite raciocinar sobre programas de forma elegante e concisa.
1. Introdução a Linguagem
de Programação Haskell
Bruno Rafael
Emanuel Franco
Iorgama Porcely
Jessyka Oliveira
27 de Novembro
2. Tópicos
Introdução a Haskell
Tipos de dados
Operadores
Criando funções
Recursão
Pattern Matching
Guards
Listas
Tuplas
3. O que é Haskell?
Linguagem de programação puramente
funcional.
Variáveis imutáveis;
Expressões em formas de funções, sem
efeitos colaterais, ou seja, a função ira
somente calcular algo e devolve-lo como
resultado.
4. O que é Haskell?
Inicialmenteessa forma pode ser visto como
uma limitação, porém:
Quando uma função é chamada duas vezes
com os mesmos parâmetros, é garantido o
retorno do mesmo resultado. Isso se chama
transparência referencial.
5. Transparência referencial
Permite
que o compilador raciocine sobre o
comportamento do programa;
Permiteque você deduza
facilmente (e até mesmo prove)
que uma função está correta;
Permitea construção de funções mais
complexas juntando diversas funções
simples
6. Haskell é preguiçoso
Não irá executar funções e calcular as coisas
antes que ele seja realmente obrigado a lhe
mostrar um resultado.
Istopermite simplificar
coisas como estruturas de
dados infinitas.
7. Exemplo
Temos a seguinte lista de números imutável:
xs = [1,2,3,4,5,6,7,8]
Função DoubleMe (Multiplica cada elemento
por 2 e retorna uma nova lista)
Queremos multiplicar nossa lista por 8.
8. Na linguagem imperativa
Fazendo:
doubleMe (doubleMe (doubleMe (xs )))
Provavelmente iria passar uma vez pela lista,
fazer uma cópia e retornar. Em seguida, ele
iria passar por mais duas vezes e retornar o
resultado.
9. Na linguagem preguiçosa
Fazendo:
doubleMe (doubleMe (doubleMe (xs )))
A função será executada
para o primeiro elemento
da lista, seguido dos
elementos seguintes.
Assim a lista é percorrida somente uma vez.
10. Haskell é estaticamente tipada
O compilador saberá no código o que é um
número, o que é uma string e assim por
diante.
Uma série de possíveis erros poderão ser
capturados em tempo de compilação.
Ex.: Tentando adicionar um número a uma
string, o compilador ira se queixar com você.
11. Inferência de Tipo
Não é necessário explicitamente identificar
cada pedaço de código com um tipo;
O sistema de tipos inteligente do Haskell
descobrirá muito sobre ele.
Ex.: Tendo a = 5 + 4, não é necessário dizer
que a é um número, pois já será identificado.
12. Elegante e Conciso
Utiliza
uma série de conceitos de alto nível;
Programas Haskell são normalmente mais
curtos do que os seus equivalentes
imperativos;
Programas mais curtos são mais fáceis de
se manter e têm menos bugs.
13. Feito por caras realmente
inteligentes
O trabalho sobre Haskell
começou em 1987 quando
uma comissão de
pesquisadores se reuniu
para projetar uma linguagem
matadora. Em 2003, o Relatório
Haskell foi publicado já com
uma versão estável da
linguagem.
14. O que preciso para começar?
Interpretador HUGS
http://cvs.haskell.org/Hugs/pages/downloadin
g.htm
Compilador GHC
http://www.haskell.org/ghc/download.html
15. HUGS – Primeiros comandos
:quit - Sai do Hugs
:? - Exibe a ajuda do Hugs
:load <caminho_do_arquivo> - Carrega um
arquivo para o Hugs
:reload - Recarrega o último arquivo
carregado
16. Operações
Pode-se utilizar todos operadores comuns
em uma só linha e todas suas regras usuais
precedentes serão obedecidas.
17. Operações
Podemos utilizar parênteses para declarar
de forma explicita a operação precedente ou
para mudá-la
18. Operações
Sevocê quiser obter números negativos,
sempre tenha a operação determinada por
parênteses.
Fazendo 5 * -3 o GHCI irá gritar com você;
Fazendo 5 * (-3) isto irá funcionar
perfeitamente
19. Operações Booleanas
Onde && refere-se a expressão
booleana and, ||refere-se a expressão
booleana or. not faz a negação de
um True ou de um False.
21. Operadores para inteiros
Além dos operadores convencionais temos:
^ : para cálculos de Potência.
ghci> 2 ^ 4
16
ghci> 4 ^ 4
256 Q
22. Funções para Inteiros
div : divisão de números
ghci> div 4 2
2
mod: resto da divisão
ghci> mod 10 3
1
23. Funções para Inteiros
succ : retorna sucessor
ghci> succ 8
9
negate: muda sinal do número
ghci> negate 10
-10
24. Funções para Inteiros
mim : retorna menor valor
ghci> mim 9 10
9
max: retorna maior valor
ghci> max 100 101
101
25. Funções para Inteiros
Fuções podem ser escritas como
operadores, e vice-versa:
ghci> 4 `div` 2
2
ghci> (+) 4 2
6
26. Funções para Inteiros
As funções tem precedencia sobre as
operações, como podemos ver abaixo:
As duas expressões são equivalentes.
27. Tipos e Funções para Float
Os mesmos dos inteiros, com mais alguns:
** : Exponenciação;
cos, sin, tag: Coseno, Seno e Tangente;
log: Logaritmo na base e;
logBase: Logaritmo em base qualquer.
28. Tipos e Funções para Float
sqrt: raiz quadrada;
ghci> sqrt 16
4.0
pi: Constante pi;
ghci> 2 * pi
6.28318530717959
29. Fazendo sua própria função
Vamos agora fazer nossa primeira função.
No editor de texto escreva:
doubleMe x = x + x
Salve como “baby.hs”.
Essa função retornará o dobro
do valor de entrada.
30. Fazendo sua própria função
Indoao local onde o arquivo foi salvo
execute os seguintes passos:
ghci> :1 baby
[1 of 1] Compiling Main ( baby.h
s, interpreted )
Ok, modules loaded: Main.
-- Função compilada, agora vamos
testar
ghci> doubleMe 9
18
ghci> doubleMe 8.3
16.6
41. Pattern Matching
Pesquisa por padrões de dados e, caso
obtenha sucesso, fazer algo com ele.
Construção sintática do Haskell.
42. Pattern Matching
Construção sintática do Haskell.
Pesquisa por padrões de dados e, caso
obtenha sucesso, fazer algo com ele.
Código:
– Simples.
– Conciso.
– Legível.
45. Pattern Matching
Exercício:
Implementar a função sayMe.hs, que diz seu
parametro de 1 até 5 ou “não está entre 1 e 5”.
46. Pattern Matching
Exercício:
Implementar uma função que diz se parametro de
1 até 5 ou “Não está entre 1 e 5”.
Dicas:
1. SayMe :: (Num a) => a → String.
2. sayMe 1 = “Um!”.
(…)
3. sayMe x = “Não está entre 1 e 5”.
51. Guards
Forma de testar se uma ou mais
propriedades são V. ou F.
Funcionam bem com Patterns.
52. Guards
Ex:Função que repreende o usuário de uma
forma específica, dependendo do seu IMC.
– Imc <= 18,5: Considerado magro.
– Imc <= 25,0: Considerado saudável.
– Imc <= 30,0: Considerado gordo.
62. Maximum
Exercício:
Implementar a Função somaLista.hs, para
somar os elementos de uma lista.
63. Maximum
Exercício:
Implementar a Função somaLista.hs, para
somar os elementos de uma lista.
Dicas:
1. sumList :: [Int] → Int.
2. Caso Base: sumList [] = 0.
3. Caso recursivo: sumList (a:as) = a + sumList
as.
64. Listas
Listas são estruturas de dados homogêneas:
– Armazena vários elementos do MESMO tipo
– Lista de caracteres
listaVogais = ['a','e','i','o','u']
– Lista de inteiros
listaNumPar = [2,4,6,8]
65. Listas
Listas são estruturas de dados homogêneas:
– Lista de caracteres
– Lista de inteiros
– Lista vazia
66. Listas
O que caracteriza uma lista?
utilizam colchetes
valores são separados por vírgulas
67. Listas
O Haskell irá reclamar da lista abaixo?
68. Listas
O Haskell irá reclamar da lista abaixo?
Sim, porque não há apenas um tipo de dado
na lista!!
70. Operadores
Pode-ser usado ainda >, <, >=, <=, ==, /=
E se as listas comparadas
são de tipos diferentes?
71. Strings – Um tipo especial
String é uma lista de caracteres
“hello” é o mesmo que ['h','e','l','l','o']
String podem usar as mesmas funções de
listas
Vamos conhecê-los?!
72. Operações com listas
++ → Unir duas listas:
:→ Acrescentar um elemento no início de
uma lista
73. Operações com listas
!! → Obter um elemento pelo seu índice
E se o índice for superior
ao tamanho da lista?
75. Operações com listas
head → retorna o primeiro elemento
tail → retorna tudo, exceto o primeiro elemento
Cuidado para não
last → retorna o último elemento Utilizá-los em
listas vazias!!
init → retorna tudo, exceto o último elemento
76. Operações com listas
length → retorna o seu tamanho
null → verifica se a lista é vazia
reverse → reverte uma lista
take→ retorna um
número desejados de
elementos da lista
77. Operações com listas
drop → similar ao take, mas
retira do início da lista
maximum → retorna o maior elemento
minimum → retorna o menor elemento
sum → retorna a soma
78. Operações com listas
product → retorna o produto
elem → verifica se o elemento pertence a lista
replicate
→ repete o mesmo
elemento em um nova lista
79. Operações com listas - Ranges
E se você precisar de uma lista com todos os
números entre 1 e 10?
Solução: [1,2,3,4,5,6,7,8,9,10]?
E se for entre 1 e 1000?
ou 10000?
80. Operações com listas - Ranges
Não!! Perda de tempo.
E se você precisar de uma lista com todos os
números entre 1 e 10? ou 1000?
ou 10000?
Solução: Utilizamos os ranges!!
81. Operações com listas - Ranges
São uma sequência aritmética de elementos
devidamente enumerados
Números e caracteres podem ser enumerados.
Ex. 1, 2, 3,…, 100 | A, B, C, ..., Z
82. Operações com listas - Ranges
E se quisermos todos os números ímpares
entre 1 e 20? Ou se quisermos sempre ter o
terceiro número entre 1 e 20?
Podemos definir etapas específicas!!
83. Tuplas
Um jeito de armazenar muitos elementos em
um único lugar
Não precisa ser homogênera
84. Tuplas
O que caracteriza uma tupla?
utilizam parênteses
valores são separados por vírgulas
85. Operadores
Pode-ser usado ainda >, <, >=, <=, ==, /=
E se as tuplas
comparadas são de
tipos/tamanhos diferentes?
86. Operações com tuplas (par)
fst → retorna seu primeiro componente
snd → retorna seu segundo componente
87. Entradas e Saídas de dados
Fornecer dados e receber dados são de
suma importância para que exista uma
interatividade maior entre usuário e máquina.
88. Entradas e Saídas de dados
Abram um editor de texto.
< main = putStr "hello, world" >
Salvem em uma pasta com o nome “teste.hs”
89. Entradas e Saídas de dados
Compilar
– ghc -o teste teste.hs
Executar
– ./teste
90. Entradas e Saídas de dados
putStr→ imprimi uma string sem pular linha
putStrLn → imprimi uma string pulando uma
linha
91. Entradas e Saídas de dados
main = do
putStrLn "Qual seu nome?"
name <- getLine
putStrLn ("Eu sou " ++ name)
92. Entradas e Saídas de dados
import Data.Char
main = do
putStrLn "Qual é o seu primeiro nome?"
firstName <- getLine
putStrLn "Qual é o seu segundo nome?"
lastName <- getLine
let bigFirstName = map toUpper firstName
bigLastName = map toUpper lastName
putStrLn $ "Olá " ++ bigFirstName ++ " " ++
bigLastName
93. Entradas e Saídas de dados
main = do
line <- getLine
if null line
then return ()
else do
putStrLn $ reverseWords line
main
reverseWords :: String -> String
reverseWords = unwords . map reverse . words
94. Entradas e Saídas de dados
main = do
return ()
return "HAHAHA"
line <- getLine
return "BLAH BLAH BLAH"
return 4
putStrLn line
95. Entradas e Saídas de dados
main = do
a <- return "Alô"
b <- return "Mundo!"
putStrLn $ a ++ " " ++ b
96. Entradas e Saídas de dados
main = do
c <- getChar
if c /= ' '
then do
putChar c
main
else return ()
97. Entradas e Saídas de dados
import Control.Monad
main = do
c <- getChar
when (c /= ' ') $ do
putChar c
main
98. Entradas e Saídas de dados
main = do
a <- getLine
b <- getLine
c <- getLine
print [a,b,c]
99. Entradas e Saídas de dados
main = do
rs <- sequence [getLine, getLine, getLine]
print rs
100. Entradas e Saídas de dados
main = do
contents <- getContents
putStr (shortLinesOnly contents)
shortLinesOnly :: String -> String
shortLinesOnly input =
let allLines = lines input
shortLines = filter (line -> length line < 15) allLines
result = unlines shortLines
in result
101. Entradas e Saídas de dados
main = do
rs <- sequence [getLine, getLine, getLine]
print rs
102. Entradas e Saídas de dados
import System.IO
main = do
contents <- readFile "/caminho/texto.txt"
putStr contents
103. Entradas e Saídas de dados
import System.IO
import Data.Char
main = do
contents <- readFile "texto.txt"
writeFile "novotexto.txt" (map toUpper contents)
104. Entradas e Saídas de dados
import System.IO
main = do
todoItem <- getLine
appendFile "novotexto2.txt" (todoItem ++ "n")
105. Referências Bibliográficas
Aprender Haskell será um grande bem para
você!
http://haskell.tailorfontela.com.br/
Programação Funcional com a linguagem
Haskell
http://www.cin.ufpe.br/~dclal/monitoria/duBoi
s.pdf