Upload
nike
View
23
Download
0
Embed Size (px)
DESCRIPTION
Programação Funcional. Tuplas e Definição de Funções Locais em Haskell. 4a. Seção de Slides. Novidades da disciplina:. Site da disciplina: http://geocities.yahoo.com.br/lpg3udesc/ Email: [email protected] Márcio Ferreira da Silva. Hoje:. Sejam as construções abaixo:. - PowerPoint PPT Presentation
Citation preview
Programação Programação FuncionalFuncional
4a. Seção de Slides
Tuplas e Definição de FunçõesTuplas e Definição de FunçõesLocais em HaskellLocais em Haskell
2
Novidades da disciplina:
• Site da disciplina: http://geocities.yahoo.com.br/lpg3udesc/
• Email: [email protected]• Márcio Ferreira da Silva
3
Hoje:
Main> sxyz 3 4 07Main> sXYZ ( 3 , 4, 0 )7
sxy x y z = x + y + z
sXYZ ( x , y, z ) = x + y + z
Sejam as construções abaixo:
Qual a diferença entre elas ?
4
Dicas
sumi :: Int -> Intsumi n | n <= 0 = 0 | otherwise = n + (observe "sumi" (n-1))
import Observe
5
Tuplas
• A linguagem Haskell permite a definição de tipos compostos, chamados de tuplas.
• Tuplas são construídas a partir de tipos mais simples.
• O tipo (t1,t2,...tn)
consiste de tuplas com valores (v1,v2,...vn)
onde v1::t1, v2::t2, vn::tn.• Enfim, fazer a composição de tipos de dados ...
6
Tuplas
• Definições de novos tipos podem ser introduzidas pelo comando type.
• Exemplo: informações sobre uma pessoa, representadas pelo nome, telefone e idade.
1 .2 .3 .
1 .2 .3 .
type Pessoa = (String, String, Int)maria :: Pessoamaria = ("Maria", "32162724", 56)
7
Tuplas
• Tuplas são usadas quando é necessário agrupar dados, com algum sentido entre eles.
• Exemplo: Uma pessoa tem uma idade, um sexo, um nome, etc
• Outra utilidade: uma função que pode retornar mais de um valor como resposta, pois está tudo encapsulado!
8
Exemplo:
Aula04> menor3maior (-4) 5 (-6)(-6,5)
menor3maior :: Int -> Int -> Int-> (Int,Int) menor3maior x y z = ( menor (menor x y) z , maior (maior x y) z)
Exemplo: Uma função que retorne o mínimo (menor valor) e também o máximo de 3 valores inteiros fornecidos:
9
Funções Auxiliares
maior :: Int -> Int -> Intmaior x y =
if x >= y then x else y
menor :: Int -> Int -> Intmenor x y =
if x <= y then x else y
10
Tuplas
• Padrões podem ser utilizados na definição de funções sobre tuplas.
• Em vez de usar uma variável x para um argumento de tipo (Int, Int), por exemplo, pode-se usar um padrão como (x,y).
1 .2 .
1 .2 .
addPair :: (Int,Int) -> IntaddPair (x,y) = x + y
11
Tuplas
1 .2 .
1 .2 .
addPair :: (Int,Int) -> IntaddPair (x,y) = x + y
34 casa com xe 32 casa com y.
34 casa com xe 32 casa com y.
addPair (34, 32)
=
12
Tuplas
addPair (34, 32)
= 34 + 32
= 66
1 .2 .
1 .2 .
addPair :: (Int,Int) -> IntaddPair (x,y) = x + y
13
Tuplas
• Importante: as duas definições seguintes são diferentes!
1 .2 .3 .4 .5 .
1 .2 .3 .4 .5 .
addPair :: (Int,Int) -> IntaddPair (x,y) = x + y
addTwo :: Int -> Int -> IntaddTwo a b = a + b
Main> addPair (34,32)66Main> addTwo 34 3266
Main> addPair (34,32)66Main> addTwo 34 3266 Visto no início da
aula
Visto no início da aula
14
Tuplas• Padrões podem conter padrões aninhados.• Isto é muito útil...
1 .2 .
1 .2 .
shift :: ((Int,Int),Int) -> (Int,(Int,Int))shift ((a,b),c) = (a,(b,c))
Main> shift ((1,2),3)(1,(2,3))
Main> shift ((1,2),3)(1,(2,3))
15
Tuplas• As funções que extraem partes de uma tupla podem ser especificadas
usando casamento de padrões.
1 .2 .3 .4 .5 .
1 .2 .3 .4 .5 .
type Pessoa = (String, String, Int)
nome :: Pessoa -> Stringfone :: Pessoa -> Stringidade :: Pessoa -> Int
16
Tuplas• Funções que extraem partes de uma tupla podem ser especificadas usando
casamento de padrões.
1 .2 .3 .4 .5 .6 .7 .8 .9 .
1 .2 .3 .4 .5 .6 .7 .8 .9 .
type Pessoa = (String, String, Int)
nome :: Pessoa -> Stringfone :: Pessoa -> Stringidade :: Pessoa -> Int
nome (n,f,i) = nfone (n,f,i) = fidade (n,f,i) = i
17
1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .
1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .
type Pessoa = (String, String, Int)
nome :: Pessoa -> Stringfone :: Pessoa -> Stringidade :: Pessoa -> Intnome (n,f,i) = nfone (n,f,i) = fidade (n,f,i) = i
maria :: Pessoamaria = ("Maria Antonia", "32162724", 56)
Main> nome maria"Maria Antonia"Main> idade maria56
Main> nome maria"Maria Antonia"Main> idade maria56
Observe que maria é uma função
Observe que maria é uma função
E nome também é uma função, cujo argumento é uma função definida
por uma tupla
E nome também é uma função, cujo argumento é uma função definida
por uma tupla
18
Tuplas• Haskell possui duas funções de extração pré-definidas para tuplas de 2
elementos (pares).
1 .2 .
1 .2 .
fst (x,y) = xsnd (x,y) = y
Main> fst (1,2)1Main> snd (1,2)2
Main> fst (1,2)1Main> snd (1,2)2
19
Definições de Funções• Por enquanto, as definições de funções estudadas
são da forma:
fun p1 p2 ... pn | g1 = e1 | g2 = e2 ... | otherwise = er
20
Definições Locais• Cada equação pode também ser seguida por uma
lista de definições locais.• Essas definições são escritas após a palavra-chave
where.
1 .2 .3 .4 .5 .6 .
1 .2 .3 .4 .5 .6 .
sumSquares :: Int -> Int -> IntsumSquares m n = sqM + sqN where sqM = m * m sqN = n * n
21
Definições Locais• Formato geral:
fun p1 p2 ... pn | g1 = e1 ... | otherwise = er where v1 = r1 v2 a1...ak = r2 ...
Definições locais podem incluir funções!
Definições locais podem incluir funções!
Indentação é importante. Define o conceito de “Bloco”
Indentação é importante. Define o conceito de “Bloco”
22
• Exemplo com definição de função local:
1 .2 .3 .4 .5 .6 .
1 .2 .3 .4 .5 .6 .
sumSquares :: Int -> Int -> IntsumSquares m n = sqM + sqN where sqM = m * m sqN = n * n
1 .2 .3 .4 .5 .
1 .2 .3 .4 .5 .
sumSquares :: Int -> Int -> IntsumSquares m n = sq m + sq n where sq x = x * x
sq é local... Visível
apenas em sumSquares
sq é local... Visível
apenas em sumSquares
23
Definições Locais• É possível fazer também definições locais a
expressões, usando a palavra-chave let.
Main> let x = 5 in x^2 + 2*x - 431
Main> let x = 5 in x^2 + 2*x - 431
• Se forem usadas 2 ou mais definições, devem ser separadas por ";" .
Main> let x = 5; y = 4 in x^2 + 2*x - y31
Main> let x = 5; y = 4 in x^2 + 2*x - y31
24
Regras de Escopo• O escopo de uma definição é a parte do programa
onde ela é visível.• As definições no primeiro nível de indentação de um
script haskell são visíveis em todo o programa.• A ordem de definição não importa.
1 .2 .3 .4 .5 .6 .
1 .2 .3 .4 .5 .6 .
isOdd, isEven :: Int -> Bool
isOdd 0 = FalseisOdd n = isEven (n-1)isEven 0 = TrueisEven n = isOdd (n-1)
25
Regras de Escopo• Definições locais (cláusulas where) têm escopo mais
reduzido, assim como as variáveis na definição de uma função.
1 .2 .3 .4 .5 .6 .7 .8 .
1 .2 .3 .4 .5 .6 .7 .8 .
maxsq x y | sqx > sqy = sqx | otherwise = sqy where sqx = sq x sqy = sq y sq :: Int -> Int sq z = z * z
Definições locais podem ser usadas antes de
serem definidas.
Definições locais podem ser usadas antes de
serem definidas.
Declaração do tipo pode ser feita localmente.
Declaração do tipo pode ser feita localmente.
26
Regras de Escopo• Definições locais (cláusulas where) têm escopo mais
reduzido, assim como as variáveis na definição de uma função.
1 .2 .3 .4 .5 .6 .7 .8 .
1 .2 .3 .4 .5 .6 .7 .8 .
maxsq x y | sqx > sqy = sqx | otherwise = sqy where sqx = sq x sqy = sq y sq :: Int -> Int sq z = z * z
Escopo de x, y, sqx, sqy e sq.
Escopo de x, y, sqx, sqy e sq.
Escopo de z.Escopo de z.
27
Regras de Escopo• Se um mesmo nome é utilizado mais de uma vez,
vale a definição mais local.
1 .2 .3 .4 .5 .6 .7 .8 .
1 .2 .3 .4 .5 .6 .7 .8 .
maxsq x y | sqx > sqy = sqx | otherwise = sqy where sqx = sq x sqy = sq y sq :: Int -> Int sq x = x * x
Nome "x" é redefinido localmente.
Nome "x" é redefinido localmente.
28
Exemplos• Problema: construir uma função
max3oc :: Int -> Int -> Int -> (Int,Int)
que retorna o máximo (maior) de 3 inteiros, e também o número de vezes que esse maior valor ocorre entre os 3.
• Exemplo de execução:
Main> max3oc 10 30 20(30,1)Main> max3oc 15 12 15(15,2)
Main> max3oc 10 30 20(30,1)Main> max3oc 15 12 15(15,2)
29
Exemplos• Solução natural: achar o máximo/maior e contar
quantas vezes ocorre entre os 3 valores.
1 .2 .3 .4 .5 .6 .7 .
1 .2 .3 .4 .5 .6 .7 .
max3oc :: Int -> Int -> Int -> (Int,Int)
max3oc x y z = (max, igCont) where max = maxi3 x y z igCont = iguais3 max x y z
30
Exemplos• Para achar o máximo entre 3 valores, pode-se usar a
função que encontra o máximo entre 2 valores.
1 .2 .3 .4 .5 .6 .7 .
1 .2 .3 .4 .5 .6 .7 .
maxi :: Int -> Int -> Intmaxi x y | x >= y = x | otherwise = y
maxi3 :: Int -> Int -> Int -> Intmaxi3 x y z = maxi x (maxi y z)
31
Exemplos• Voltando ao problema inicial...
1 .2 .3 .4 .5 .
1 .2 .3 .4 .5 .
max3oc x y z = (max, igCont) where max = maxi3 x y z igCont = iguais3 max x y z
• Como definir
iguais3 :: Int -> Int -> Int -> Int -> Int
???
32
Exemplos• Uma solução:
1 .2 .3 .4 .5 .6 .
1 .2 .3 .4 .5 .6 .
iguais3 v a b c = va + vb + vc where va = if a==v then 1 else 0 vb = if b==v then 1 else 0 vc = if c==v then 1 else 0
• OBS: if c then e1 else e2 retorna e1 se c for True, e retorna e2, se c for False.
33
Exemplos
1 .2 .3 .4 .5 .6 .
1 .2 .3 .4 .5 .6 .
iguais3 v a b c = va + vb + vc where va = if a==v then 1 else 0 vb = if b==v then 1 else 0 vc = if c==v then 1 else 0
• A definição pode ser melhorada, eliminando a repetição de 3 comparações análogas:
34
Exemplos• A definição pode ser melhorada, eliminando a
repetição de 3 comparações análogas:
1 .2 .3 .4 .5 .
1 .2 .3 .4 .5 .
iguais3 v a b c = igv a + igv b + igv c where igv :: Int -> Int igv x = if x==v then 1 else 0
O valor ”v" é maior já encontrado
O valor ”v" é maior já encontrado
35
Mais Exemplos ..Um sistema de menu’s....
main =imp_menu
imp_menu =do putStrLn "\n ********************" putStrLn " Opção i: Incluir " putStrLn " Opção e: Excluir " putStrLn " Opção s: Sair " putStrLn " ********************" putStr " Digite i, e ou s: " le_opcao
Criando um executável... Tudo começa
em main
Criando um executável... Tudo começa
em main
36
Continuando ..
le_opcao =do opcao <- getChar f_menu opcao
f_menu i = do
case (i) of'i' -> putStrLn "\n Chamou a funcao 1 !!!" 'e' -> putStrLn "\n Chamou a funcao 2 !!!"'s' -> putStrLn "\n Chamou a funcao 3 !!!"_ -> imp_menu
37
Finalizando ...• Temos palavras reservadas como: do, case, let, where, in, if, then, else, of, etc, a serem utilizadas nas funções;• Diríamos que é a parte sequencial das linguagens funcionais, que ainda nos prende as Máquinas de Von Neumann (sequenciais);• Contudo, o uso delas pode ser contornado (se quiser, opcional), usando um estilo 100% funcional de se programar;• Estas seguem regras de escopo;• Estas seguem uma identação de blocos. Cuidar...