Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em...

41
Programação Programação Funcional Funcional 3a. Seção de Slides Padrões Simples e Definição Padrões Simples e Definição de Operadores em Haskell de Operadores em Haskell

Transcript of Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em...

Page 1: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

Programação Programação FuncionalFuncional

3a. Seção de Slides

Padrões Simples e Definição de Padrões Simples e Definição de Operadores em HaskellOperadores em Haskell

Page 2: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

2

Hoje:

• Alguns comentários e respostas das aulas passadas

• Operadores, associatividade• Padrões e casamentos• Tipos Bool, Carácteres e String e Float

Page 3: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

3

Obs. do Lab #2Seja calcular: 7^0 + 7^1 + ... + 7^n

Logo uma função de 7^n é dada por:

pot_7 0 = 1pot_7 n = 7 * pot_7 (n-1)

Aplicar uma recursão sobre: 7^0 + 7^1 + ... + 7^n

Então:

serie_7 pot_7 0 = pot_7 0serie_7 pot_7 n = pot_7 n + serie_7 pot_7 (n-1)

Aula02> pot_7 249Aula02> serie_7 pot_7 257Aula02> :type serie_7

serie_7 :: (Num a, Num b) => (b -> a) -> b -> a

Page 4: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

4

Correções na Apostila

--Correção na apostila do Michell

-- função ... SOMA ESPECIALs_michell f 1 = 1s_michell f n = f n + s_michell f (n-1)

(página 11, no final)

f x | x == 0 = 10| x < 0 = abs (x) | x > 0 = x - f (x-1)

Faltava também definir f ....

Page 5: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

5

Perguntas:

write :: String -> String write x = x

Main> write "xxxx yyyy""xxxx yyyy"Main> write xxxx yyyyERROR - Undefined variable "yyyy"

Main>

Page 6: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

6

Um pouco sobre entradas/saídas:

....putStrLn “Alo mundo”....nome_string <- getLine -- Não usa o igual... pois não é uma

-- função....

Page 7: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

7

Comentários:ou_excl False False = Falseou_excl True True = Falseou_excl _ _ = True

Main> ou_excl True FalseTrue Main> ou_excl (4 > 6) (3 < 8)True

Obs. No uso de parênteses.... são necessários

Page 8: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

8

Operadores

• Como visto: a linguagem Haskell contém vários operadores, como: +, -, *, /, `div`, `mod`, ^, etc.

• Operadores são infixos, o que significa que são escritos entre os seus argumentos.

• Parênteses podem ser usados em qualquer operação: (((4+8)*3)+2)

• Propriedades que auxiliam na eliminação de parênteses: associatividade e prioridade de operadores.

Page 9: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

9

Associatividade• Uma operação op é associativa se

(x op y) op z = x op (y op z)• Operações associativas dispensam parênteses.• Ou seja, não interessa a ordem de como os cálculos

são feitos.• Uma operação não associativa é classificada como:

– associativa à esquerda; ou– associativa à direita.

Page 10: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

10

AssociatividadeMain> 4 + 2 + 17Main> (4 - 2) - 11Main> 4 - (2 - 1)3Main> 4 - 2 - 11

Prelude> 9-(7+2)0Prelude> (9-7)+24Prelude> 9-7+24

Main> 4 + 2 + 17Main> (4 - 2) - 11Main> 4 - (2 - 1)3Main> 4 - 2 - 11

Prelude> 9-(7+2)0Prelude> (9-7)+24Prelude> 9-7+24

Adição (+) é associativa.

Adição (+) é associativa.

Subtração (-) nãoé associativa.

Subtração (-) nãoé associativa.

Subtração (-) nãoé associativa.

Subtração (-) nãoé associativa.

Subtração (-) é associativa à esquerda.

Subtração (-) é associativa à esquerda.

Finalmente, na mistura, a associativa

à esquerda

Finalmente, na mistura, a associativa

à esquerda

Page 11: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

11

Precedência de operadores

• A associatividade define a ordem de computação de expressões envolvendo mais de uma ocorrência de um mesmo operador. Ex: 2^3^2Prelude> 2^3^2512Prelude> 2^9512

• E quando operadores diferentes são utilizados?• Por exemplo:

2+3*4 = 143^4*2 = 162

• Alguns operadores têm precedência maior do que outros.

Exponenciação é associativa à direita.

Exponenciação é associativa à direita.

Page 12: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

12

Precedência de operadores

Main> 2 + 3 * 414Main> 2 ^ 3 * 432

Main> 2 + 3 * 414Main> 2 ^ 3 * 432

Operador * tem precedência 7, enquanto + tem prioridade 6.

Operador * tem precedência 7, enquanto + tem prioridade 6.

Operador ^ tem precedência 8.Operador ^ tem precedência 8.

Page 13: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

13

Precedência de operadores

Main> 2 + 3 * 414Main> 2 ^ 3 * 432Main> fat 4 + 1???????????????????

Main> 2 + 3 * 414Main> 2 ^ 3 * 432Main> fat 4 + 1???????????????????

1 fat :: Int -> Int2 fat n3 | n <= 0 = 14 | otherwise = n * fat (n-1)

1 fat :: Int -> Int2 fat n3 | n <= 0 = 14 | otherwise = n * fat (n-1)

Page 14: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

14

Precedência de operadores

Main> 2 + 3 * 414Main> 2 ^ 3 * 432Main> fat 4 + 1

25

Main> 2 + 3 * 414Main> 2 ^ 3 * 432Main> fat 4 + 1

25Aplicação de função tem

precedência máxima.

Aplicação de função temprecedência máxima.

1 fat :: Int -> Int2 fat n3 | n <= 0 = 14 | otherwise = n * fat (n-1)

1 fat :: Int -> Int2 fat n3 | n <= 0 = 14 | otherwise = n * fat (n-1)

Tabela de associatividade eprecedências pode ser encontrada

no Apêndice E do livro-texto.

Tabela de associatividade eprecedências pode ser encontrada

no Apêndice E do livro-texto.

Page 15: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

15

Precedência de operadores

Main> fat (-1)1

Main> fat (-1)1

1 fat :: Int -> Int2 fat n3 | n <= 0 = 14 | otherwise = n * fat (n-1)

1 fat :: Int -> Int2 fat n3 | n <= 0 = 14 | otherwise = n * fat (n-1)

Page 16: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

16

Precedência de operadores

Main> fat (-1)0Main> fat -1ERROR - Illegal class constraint in inferred type

Main> fat (-1)0Main> fat -1ERROR - Illegal class constraint in inferred type

1 fat :: Int -> Int2 fat n3 | n <= 0 = 14 | otherwise = n * fat (n-1)

1 fat :: Int -> Int2 fat n3 | n <= 0 = 14 | otherwise = n * fat (n-1)

Page 17: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

17

Definindo Operadores• Haskell permite a definição de novos operadores.• Os nomes dos operadores são formados por:

! # $ % & * + . / < = > ? @ \ ^ | : - ~

• Restrições:– nomes não podem começar por ":"– "-" e "~" só podem ser o primeiro símbolo do nome– símbolos (e combinações) reservados:

:: => = @ \ | ^ <- ->

• Mudar associatividade ou precedência:

infix infixl infixr

Define operador como não associativo.

Define operador como não associativo.

Define operador como associativo à esquerda.

Define operador como associativo à esquerda.

Define operador como associativo à direita.

Define operador como associativo à direita.

Page 18: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

18

Definindo Operadores1 infixl 7 &&&1 infixl 7 &&&

Define operador &&& como associativo à esquerda,

com predência 7.

Define operador &&& como associativo à esquerda,

com predência 7.

Page 19: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

19

Definindo Operadores1 infixl 7 &&&23 (&&&) :: Int -> Int -> Int4 a &&& b5 | a > b = a6 | otherwise = b

1 infixl 7 &&&23 (&&&) :: Int -> Int -> Int4 a &&& b5 | a > b = a6 | otherwise = b

Main> 10 &&& 2020

Main> 10 &&& 2020

Page 20: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

20

Definições com Padrões• As definições de funções vistas até agora consistem

de uma única equação.• É possível definir uma função usando várias

equações.• As equações devem especificar como a função se

comporta quando aplicada a determinados padrões.• Os padrões mais simples são variáveis e

constantes.

Page 21: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

21

Definições com Padrões

1 .2 .

1 .2 .

totalSales 0 = sales 0totalSales n = totalSales (n-1) + (sales n)

1 totalSales :: Int -> Int2 totalSales n3 | n == 0 = sales 04 | otherwise = totalSales (n-1) + (sales n)

1 totalSales :: Int -> Int2 totalSales n3 | n == 0 = sales 04 | otherwise = totalSales (n-1) + (sales n)

• Versão anterior - uma equação condicional:

• Nova versão - usando padrões (“pattern matching”):

Page 22: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

22

Definições com Padrões

1 .2 .

1 .2 .

totalSales 0 = sales 0totalSales n = totalSales (n-1) + (sales n)

• A primeira equação é aplicada somente ao valor 0.• A segunda se aplica a todos os outros casos.• Regra geral: utilizar a primeira equação que "casa"

com os argumentos, na ordem especificada.• Um argumento a casa com um padrão p se:

– p é uma constante e a é igual a p ; ou– p é uma variável.

Page 23: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

23

Definições com Padrões

1 .2 .3 .

1 .2 .3 .

is Zero :: Int -> BoolisZero 0 = TrueisZero _ = False

• O padrão "_" casa com qualquer argumento (“Prolog like”).• É usado quando o valor do argumento não é necessário no

lado direito da equação.

Page 24: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

24

Definições com Padrões

1 .2 .3 .4 .5 .6 .7 .

1 .2 .3 .4 .5 .6 .7 .

fib :: Int -> Int

fib 0 = 0fib 1 = 1fib n | n > 1 = fib (n-1) + fib (n-2) | otherwise = 0

• Exemplo envolvendo padrões e equação condicional:

Page 25: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

25

Programando com Booleanos

• Os valores booleanos são representados pelas constantes False e True, do tipo Bool.

• Operadores:&& ("e" lógico) || ("ou" lógico) not (negação)

• Semântica dos operadores: t1 t2 t1 && t2 t1 || t2 t1 not t1 T T T T T F T F F T F T F T F T F F F F

Page 26: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

26

Programando com Booleanos

• Uma definição para "not":

1 .2 .3 .

1 .2 .3 .

meuNot :: Bool -> BoolmeuNot True = FalsemeuNot False = True

Page 27: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

27

Programando com Booleanos

• "ou exclusivo" - retorna True se exatamente um dos argumentos for True:

exOr :: Bool -> Bool -> Bool

exOr x y = (x || y) && not (x && y)

(Veio da definição do Ou-exclusivo... Lógica)

• Definição usando padrões:

1 .2 .

1 .2 .

exOr False x = xexOr True x = not x

Page 28: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

28

Programando com Booleanos

• Construir uma função isZeroDay que, dado o número de um dia, retorne:– True, se o número de unidades vendidas (função sales) no

dia é zero;– False, caso contrário.

1 .2 .3 .4 .

1 .2 .3 .4 .

isZeroDay :: Int -> BoolisZeroDay n | sales n == 0 = True | otherwise = False

Page 29: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

29

Programando com Booleanos

• Quando a expressão sales n == 0 tem valor True, a função retorna True.

• Quando a expressão sales n == 0 tem valor False, a função retorna False.

1 .2 .3 .4 .

1 .2 .3 .4 .

isZeroDay :: Int -> BoolisZeroDay n | sales n == 0 = True | otherwise = False

Page 30: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

30

Programando com Booleanos

• Simplificação:

1 .2 .3 .4 .

1 .2 .3 .4 .

isZeroDay :: Int -> BoolisZeroDay n | sales n == 0 = True | otherwise = False

Esta função será reusada em seguida....

1 .2 .

1 .2 .

isZeroDay :: Int -> BoolisZeroDay n = (sales n == 0)

Ao invés do True ou False... A própria expressão! Humm bem elegante...

Page 31: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

31

Programando com Booleanos

• Construir uma função zeroInPeriod que, dado o número de um dia, retorne:– True, se não foi vendida nenhuma unidade do produto em

algum dia do período 0,...,n;– False, caso contrário.

1 .2 .3 .4 .

1 .2 .3 .4 .

zeroInPeriod :: Int -> Bool

zeroInPeriod 0 = isZeroDay 0zeroInPeriod n = ????????????????

Page 32: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

32

Programando com Booleanos

1 .2 .3 .4 .

1 .2 .3 .4 .

zeroInPeriod :: Int -> Bool

zeroInPeriod 0 = isZeroDay 0zeroInPeriod n =

... sales (n-1)sales 1sales 0 sales n

zeroInPeriod (n-1) isZeroDay n

Page 33: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

33

Programando com Booleanos

1 .2 .3 .4 .

1 .2 .3 .4 .

zeroInPeriod :: Int -> Bool

zeroInPeriod 0 = isZeroDay 0zeroInPeriod n = zeroInPeriod (n-1) || isZeroDay n

... sales (n-1)sales 1sales 0 sales n

zeroInPeriod (n-1) ||zeroInPeriod = isZeroDay n

Page 34: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

34

Caracteres e Strings

• Char : tipo de Haskell associado a caracteres.• Caracteres individuais são inseridos em aspas

simples. Exemplos: ´d´, ´3´.• Caracteres especiais:

´\t´ tab

´\n´ new line

´\\´ barra invertida

´\´´ aspa simples

´\"´ aspa dupla

´\97´ caractere ´a´

Page 35: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

35

Caracteres e Strings

• Haskell utiliza a codificação padrão ASCII para caracteres.

• As funções chr e ord são usadas para conversões.

Main> chr 97´a´Main> ord ´A´65

Main> chr 97´a´Main> ord ´A´65

Page 36: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

36

Caracteres e Strings

• Conversão de letra minúscula para maiúscula:

1 .2 .3 .4 .

1 .2 .3 .4 .

offset = ord ´A´ - ord ´a´

capitalize :: Char -> Charcapitalize ch = chr (ord ch + offset)

• Verificar se um caractere é um dígito:

1 .2 .

1 .2 .

isDigit :: Char -> BoolisDigit ch = (´0´<= ch) && (ch <= ´9´)

Page 37: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

37

Caracteres e Strings

• Strings de caracteres pertencem ao tipo String.• São inseridas entre aspas duplas. Exemplos:

"abcdef"

"uma linha\noutra linha"

""

"O caractere \´a\´ : \97"• Strings são concatenadas usando o operador ++• Ex: “alo, ” ++ “ bom “ ++ “ dia “

Page 38: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

38

Caracteres e Strings

• Haskell permite que novos tipos sejam criados, usando a palavra-chave type.

• O tipo String é, na realidade, uma lista de caracteres:

type String = [Char]• As operações que manipulam listas (duas aulas a

frente) podem ser usadas também para strings.• Como no Prolog: “[“ .... “]” (colchetes)... são usados

para especificar uma lista, no caso: “uma string é uma lista de carácteres”

Page 39: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

39

Números de Ponto Flutuante

• Números de ponto flutuante são representados, em Haskell, pelos tipos Float e Double. Exemplos:

3.141592

-1.2345987.654

• Haskell usa também notação científica:

9.87654e02 = 9.87654*10 = 987.654

31415.92e-4 = 31415.92*10 = 3.141592

2

-4

Page 40: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

40

Números de Ponto Flutuante

• Haskell oferece uma série de funções que atuam sobre números de ponto flutuante.

Main> sin (pi/2)1.0Main> 1.1 ^ 102.59374Main> 1.1 ^ 102.59374Main> 1.1 ** 10.02.59374Main> 2.5**(3.5)24.7053 Main> sqrt 21.41421

Main> sin (pi/2)1.0Main> 1.1 ^ 102.59374Main> 1.1 ^ 102.59374Main> 1.1 ** 10.02.59374Main> 2.5**(3.5)24.7053 Main> sqrt 21.41421

Page 41: Programação Funcional 3a. Seção de Slides Padrões Simples e Definição de Operadores em Haskell.

41

Números de Ponto Flutuante

Main> round 2.492Main> ceiling 2.493Main> floor 2.492Main> log 20.693147main> logBase 2 164.0

Main> round 2.492Main> ceiling 2.493Main> floor 2.492Main> log 20.693147main> logBase 2 164.0