PNP - Capítulo 1 - Haskell

Fazer download em pptx, pdf ou txt
Fazer download em pptx, pdf ou txt
Você está na página 1de 37

Programação Não

Procedimental
Haskell - Cap 1
 

Docentes: Padoca Mateus


Calado
FCUAN-C S2020 Paulino Jonas
Capítulo 1
 Conceitos fundamentais:
o Introdução, operadores, secções. funções,
redução, identificadores, identação e
comentários, recursividade, tipos de dados
(básicos e compostos), valores, listas;

o Estruturas de condição (guardas, if, case),


Funções lâmbdas, definição local;
o Manipular funções da Prelude (Lista e
Túpla), Polimorfismo;
Paradigmas de Programação

 Procedimental Estilos/Origem

• Assembly, Fortran, Pascal, ...


Imperativo
 Orientado por Objecto
• Smaltalk, C++, Delphi, ...

 Lógica
• Prolog, Trilogy, Parlog, ...
Declarativo
 Funcional
• Lisp, Hugs, Haskel, ...
Paradigma Funcional

 Um programa é simplesmente uma


função;

 Sua execução significa a avaliação


dessa função (redução).
Imperativo X Declarativo

Programa: Programa:
sequência de sequência de
comandos, funções mais
procedimentos que simples;
transformam
variáveis;

Execução:
Execução: recursiva;
sequencial
História do Haskell

Nomeada em homenagem ao lógico


Haskell Brooks Curry, como uma base
para linguagens funcionais.

Haskell é funcional (isto é, tudo é feito com


chamadas de funções) e implicitamente
tipada.

Haskell B. Curry (1900 -


1982)
História do Haskell

• versão: 1 de abril de 1990;


• versão 1.1 Agosto de 1991,
• versão 1.2 em Março de 1992,
• versão 1.3 Maio de 1996
• versão 1.4 em abril de 1997.

• Haskell 98, Janeiro de 1999 - versão mínima, estável


e portável da linguagem e o biblioteca para ensino.

Hugs e GHC consideradas os padrões.


Operadores Aritmético

 + adição
 - subtração
 * multiplicação
 / divisão fracionária
 ^ potência (expoente inteiro)
 div quociente (divisão inteira)
 mod resto (divisão inteira)
 sqrt raiz quadrada
Op. Relacional e Lógico

 == igualdade
 /= diferença
 < > <= >= comparações
 && retorna verdade todas
preposições forem verdadeiras
 || retorna Verdade se pelo menos
uma for verdadeira
 not inverte o valor booleano
Seccão
 Qualquer operador binário pode ser usado
como função de dois argumentos
escrevendo-o entre parentêsis.

o > 1+2
o > (+) 1 2
o > (+1) 2
o > (2+) 1
o > mod 5 2
o > div 2 4
Funções
 Os argumentos de funções são separados
por espaços:

Haskell Matemática
fx f(x)
f (g x) f(g(x))
f (g x) (h x) f(g(x),h(x))
fxy+1 f(x, y) +1
f x (y+1) f(x, y +1)
sqrt x + 1 (√x) +1
sqrt (x + 1) √(x +1)
Funções
 Definições de funções em um ficheiro:

o dobro x = x + x
o quadruplo x = dobro (dobro x)

 Execução:
 > dobro 2
o 4
 > quadruplo 2
o 8
Exercício: Criar uma função que acha média de
dois números.
Redução ou derivação
 Simular o comportamento da
função:
o f1 c = c * 2 + 32
• > f1 4

o f2 k = k - 273

?
• > f2 2

o f1 c = c * 2 + 32
o f2 k = k - 273
o f3 k = f1 (f2 k)
• > f3 300
Funções recursivas
 Aplicando a redução:

soma 0 = 0
soma n = n + soma (n-1)
> soma 5

?
fact 0 = 1
fact n =n * fact (n-1)
>fact 5
Identificadores

 Os nomes de funções e argumentos devem


começar por letras mínusculas e podem incluir
letras, dígitos, sublinhados e apóstrofes:
o fun1 x_2 y' fooBar

 As seguintes palavras reservadas não podem ser


usadas como identificadores:
o case class data default deriving do else if
import in infix infixl infixr instance let
module newtype of then type where
Identação e comentários:
 As definições de novas funções devem
começar na mesma coluna:

- - Este é um comentário simples


{-
Este comentário
Contém múltiplas linhas
-}
Tipos e Valores
 Um tipo especifica um conjunto de valores
que será armazenado;
o Por exemplo, o tipo Bool contém dois
valores lógicos: True e False

 Erros de tipos
o Algumas operações só fazem sentido com
valores de determinados tipos.
o Por exemplo: não faz sentido somar
números e valores lógicos.
o > 1 + False
• ERRO
Tipos e Valores

 Tipos básicos ou simples:


o Bool valores lógicos: True, False
o Char carateres simples: 'A', ‘1', '?', '\n'
o String sequências de carateres: "Aba",
"U40 “, “2"
o Int inteiros de precisão fixa (32 ou 64-
bits)
o Integer inteiros de precisão arbitrária
(apenas limitados pela memória do
computador);
o Float vírgula flutuante de precisão
simples;
Tipos e Valores

 Definição:
 e::T para indicar que a expressão e
admite o tipo T.
soma::Int->Int ->Int
soma x y= x+y

soma::Double>Double ->Double
soma x y= x+y
Obs: Identificar o tipo de dados de uma
expressão:

:t True
Tipos e Valores

 Exercícios:
o Função que verifica se um número é

?
par.

o Função que verifica se um número é


ímpar.

o Função que verifica se um número a


é maior que um número b.
Tipos compostos
 Listas [T]: Todos elementos são
do tipo T
• Exemplos:
• [2,3,4,5,6] :: [Int]
• [‘u’,’a’,’n’]::[Char]
• [2.2,3.4]::[Float]

 Túplas (T1,T2,T3,...,Tn): O 1º
elemento é do Tipo T1, 2º
elemento do tipo T2, etc.
• Exemplos:
Túpla
o Funções :

fst(a,b): Retorna o primeiro elemento de


uma túpla com dois elementos;

snd(a,b): Retorma o segundo elemento


de uma túpla com dois elementos.

Exemplos:
• fst(2,5)
• snd( (3,2, 4.5, ’3’),”angola”)
Túpla
 Exemplos de aplicação:
soma::(Int,Int,Int)->Int
soma (a,b,c)=a+b-c

somaSubtracao::(Int,Int)-
>(Int,Int)
somaSubtracao (a,b) =
(a+b , a-b)

Obs: A tupla vazia () é o único valor do tipo


Lista
 Exemplos de aplicação:
soma :: [Int]->Int
soma [a,b,c] = a+b-c

somaSubtracao :: (Int,Int)->[Int]
somaSubtracao (a,b) = [a+b , a-b]

Obs: Uma lista é uma sequência de tamanho


variável de elementos dum mesmo tipo.
A lista vazia [ ] admite qualquer tipo de lista [ T ]
Prelude
Algumas funções :
 head :: [a]->a retorna o primeiro elemento
da lista;
 tail :: [a]->[a] retorma o resto da lista
excepto a cabeça;
 take :: Int->[a]->[a] retorna os n primeiros
elementos;
 drop :: Int->[a]->[a] remove os n
primeiros elementos;
 reverse :: [a]->[a] inverte os elementos da
lista;
 last :: [a]->a retorna o último elemento da
Prelude

Algumas funções :
 sum :: Num a => [a] -> a soma todos
elementos númericos de uma lista;
 product :: Num a => [a] -> a multiplica todos
elementos númericos de uma lista;
 zip :: [a] -> [b] -> [(a,b)] retorna o produto
cartesiano (em túplas) dos elementos da lista 1
com a lista 2;
 unzip :: [(a, b)] -> ([a], [b]) retorna uma túpla
com duas listas;
 even :: Int->Bool verificada se um número
inteiro é par

Listas por compreensão
 É uma notação matemática (conceitos de
conjuntos):
Matemática Haskell
{x | x E {1,2,3,4,5,6}} [x | x<-[1,2,3,4,5,6]
{n|n E {9,8,-2,-10,3} ,0 <=n+2 [n | n<-[9,8,-2,-10,3], 0<=n+2,
<=10 n+2<=10]
{2x|x E {10,3,7,2}} [ 2*x | x <- [10,3,7,2] ]
{2x|x E {10,3,7,2},x<10} [ 2*x | x<- [10,3,7,2] , x<10 ]
{(x,y) | x E {3,4,5}, y E [(x,y) | X<-[3,4,5], Y<-[9,10] ]
{9,10}}
{1,2,3,4,5,6} [x | x<-[1..6]] ou tambem [1..6]
{1,3,5,7,9} [x | x<-[1,3..9]] ou tambem
[1,3..6]
 Obs.: a
{‘a’,’b’..’z’} vírgula na lista representa o operador &&
[‘a’..’z’]
(e);
Representação de Listas
Definição Notação Compreensão
[1,2,3] 1:[2,3] = 1:2:[3]= 1:2:3 : [x | x<-[1,2,3,4,5]]
[]
Decomposição da lista:
(x : xs) => x será a cabeça e o xs o resto da
lista
(x:y : _) => x será o cabeça, o y o segundo
elemento, e o resto descarto;
(_:xs) => descarta o primeiro elemento e fica
com o resto.
Obs: _ Representa variável anónima
++ Concatena duas listas
: insere um elemento no princípio da lista. Ex: 3:
[4,5,6]
Listas por compreensão

 Dada uma lista, apresenta o equivalente em


compreensão (haskell):
o [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,1
9,20]
o [2,4,6,8,10,12,14,16,18,20]
o [10,9,8,7,6,5,4,3,2,1,0]

 Dada uma lista por compreensão, apresenta o


seu resultado:
o [ x^2 | x<-[1..5] ]
o [ x^2 | x<-[1..6],(x-1) < 10]
o [(2*x,y-1) | x<-[1,2],y<-[3,2]]
Estrutura de condição
 ‘ if...then...else... ’.
 Exemplo 1:
absoluto :: Float ->Float
absoluto x = if x>=0 then x
else (-1)*x
 Exemplo 2:
sinal :: Int -> Int
sinal x = if x>0 then 1
else if x == 0 then 0
else -1
 Em Haskell, a alternativa ‘else’ é obrigatória.
Estrutura de condição
 ‘ Guardas’.

sinal :: Int -> Int


sinal x | x>0 = 1
| x==0 = 0
| otherwise = -1
 A alternativa ‘otherwise’ é executada se nenhuma
das alternativas acima for verdadeira.
Estrutura de condição
 ‘ case x of’.

ver::Int->Bool
ver x = case x of
1 -> True
2 -> True
_ -> False

 A alternativa ‘_’ é executada se nenhuma das


alternativas acima for verdadeira.
Função Lambda

 Podemos definir uma função anónima (i.e. sem


nome) usando uma expressão-lambda.

 Exemplo:
o (\x -> 2*x+1) 2
o (\x y-> x+y) 5 8
o (\x -> [1..x]) 4
Definições Locais
 Há duas formas de fazer definições locais
utilizando:
o Let .. in primeiro define-se depois utiliza-se;
f::Int->Int->Int
fyz= let
c=10
soma y z= y+z+c
in soma y z
• where primeiro utiliza depois define-se o
valor.
f::Int->Int->Int
f a b = a+b+c+d
where c=10
Definições Locais
 Exercícios:
o f1 = Let
• c = 10
Qual será o resultado:
• (a,b) = (3*c, f 2)  f1

?
• f x = x+7*c
• In f a + f b

o testa y = 3 + f y + f a + f b
• where c = 10
Qual será o resultado :
• (a,b) = (3*c, f  testa 5
2)
• f x = x +7*c
Capítulo 2

 Conceitos avançados 1:
o Módulo
o Funções de Ordem Superior
o Entrada e Saída de Dados
o Ordenação Quick Sort
o Ordenação Insert Sort
Capítulo 3

 Conceitos avançados 2:
o Classes, Objectos, Padrão @, Tipos
Sinónimos e Abstratos (Algébricos);
o Algorítmos e Estruturas de Dados
(Árvore e Grafo);
o Ficheiros
 Conceitos avançados 3:
o Projecto 1

Você também pode gostar