programação funcional

37
Programação Programação Funcional Funcional 4a. Seção de Slides Tuplas e Definição de Tuplas e Definição de Funções Funções Locais em Haskell Locais em Haskell

Upload: anisa

Post on 31-Jan-2016

24 views

Category:

Documents


0 download

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

TRANSCRIPT

Page 1: Programação Funcional

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

Page 2: Programação Funcional

2

Novidades da disciplina:

• Site da disciplina: http://geocities.yahoo.com.br/lpg3udesc/

• Email: [email protected]• Márcio Ferreira da Silva

Page 3: Programação Funcional

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 ?

Page 4: Programação Funcional

4

Dicas

sumi :: Int -> Intsumi n | n <= 0 = 0 | otherwise = n + (observe "sumi" (n-1))

import Observe

Page 5: Programação Funcional

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 ...

Page 6: Programação Funcional

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)

Page 7: Programação Funcional

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!

Page 8: Programação Funcional

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:

Page 9: Programação Funcional

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

Page 10: Programação Funcional

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

Page 11: Programação Funcional

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)

=

Page 12: Programação Funcional

12

Tuplas

addPair (34, 32)

= 34 + 32

= 66

1 .2 .

1 .2 .

addPair :: (Int,Int) -> IntaddPair (x,y) = x + y

Page 13: Programação Funcional

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

Page 14: Programação Funcional

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))

Page 15: Programação Funcional

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

Page 16: Programação Funcional

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

Page 17: Programação Funcional

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

Page 18: Programação Funcional

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

Page 19: Programação Funcional

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

Page 20: Programação Funcional

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

Page 21: Programação Funcional

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”

Page 22: Programação Funcional

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

Page 23: Programação Funcional

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

Page 24: Programação Funcional

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)

Page 25: Programação Funcional

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.

Page 26: Programação Funcional

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.

Page 27: Programação Funcional

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.

Page 28: Programação Funcional

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)

Page 29: Programação Funcional

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

Page 30: Programação Funcional

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)

Page 31: Programação Funcional

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

???

Page 32: Programação Funcional

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.

Page 33: Programação Funcional

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:

Page 34: Programação Funcional

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

Page 35: Programação Funcional

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

Page 36: Programação Funcional

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

Page 37: Programação Funcional

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...