programação funcional tipos básicos e programas simples em haskell 2a. seção de slides

36
Programação Programação Funcional Funcional Tipos Básicos e Tipos Básicos e Programas Simples em Programas Simples em Haskell Haskell 2a. Seção de Slides

Upload: internet

Post on 18-Apr-2015

120 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

Programação Programação FuncionalFuncional

Tipos Básicos eTipos Básicos eProgramas Simples em HaskellProgramas Simples em Haskell

2a. Seção de Slides

Page 2: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

2

Méritos para:

• Vladimir Oliveira Di Iorio (http://www.dpi.ufv.br/~vladimir/)

Page 3: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

3

Hoje, ... Tipos de dados (Int)

• Apesar de hoje falarmos sobre tipos de dados, em Haskell o interpretador procura advinhar (sempre) o tipo de dado que voce está usando.

• Mais tarde... Será importante => classes de tipos

• Há uma hierarquia de tipos com classes etc: ver figura botão no winhugs

• Logo, não se preocupe...

Page 4: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

4

Números Inteiros

• Na linguagem Haskell, o tipo de dados Int representa os números inteiros.

• O valor máximo de Int é 2147483647.• O tipo Integer também representa números

inteiros, sem restrição de tamanho.• A vantagem de usar Int é um possível ganho em

eficiência (depende da implementação).

Page 5: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

5

Números e Operações (1)• Operações aritméticas: +, -, *, /, div, mod, abs.• Comparação: >, <, >=, <=, ==, /=.• Exemplos:

Main> 5 + 38Main> 10 <= 20TrueMain> 10 / 33.33333

Main> 5 + 38Main> 10 <= 20TrueMain> 10 / 33.33333

Page 6: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

6

Números e Operações (2)Main> div 22 54Main> mod 12 52Main> 12 `mod` 52Main> (+) 5 38Prelude> (/) 10 3

3.33333

Main> div 22 54Main> mod 12 52Main> 12 `mod` 52Main> (+) 5 38Prelude> (/) 10 3

3.33333

• Qualquer função com 2 parâmetros pode ser usada na forma infixa, usando `` (sinais tipo crase)

• Operadores entre parênteses são tratados como funções.

Page 7: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

7

Números e Operações (3)• Alguns cuidados:• Exemplos:

Prelude> mod 13 53Prelude> 13 'mod’ 5ERROR - Improperly terminated character constantPrelude> 13 `mod` 53Prelude>

Page 8: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

8

Programas com Inteiros• Suponha uma função sales :: Int -> Int .

• A função sales retorna o número de unidades vendidas, de um determinado produto, se for fornecido o número do dia desejado.

• Os dias são numerados como 0,1,2 ...

Main> sales 325Main> sales 012

Main> sales 325Main> sales 012

1 sales :: Int -> Int2 sales x3 | x == 0 = 124 | x == 1 = 205 | x == 2 = 186 | x == 3 = 257 | otherwise = 0

1 sales :: Int -> Int2 sales x3 | x == 0 = 124 | x == 1 = 205 | x == 2 = 186 | x == 3 = 257 | otherwise = 0 Uma definição

para sales.

Uma definiçãopara sales.

Page 9: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

9

Programas com Inteiros• Suponha uma função sales :: Int -> Int .

• Leia-se: “sales tem os tipos... devolvendo o tipo ...”

• A função sales retorna o número de unidades vendidas, de um determinado produto, se for fornecido o número do dia desejado.

• Os dias são numerados como 0,1,2 ...

Main> sales 39Main> sales 03

Main> sales 39Main> sales 03

1 sales :: Int -> Int2 sales x =3 x `mod` 5 -- mod x 54 + (x+10) `mod` 7

1 sales :: Int -> Int2 sales x =3 x `mod` 5 -- mod x 54 + (x+10) `mod` 7

Outra definiçãopara sales.

Outra definiçãopara sales.

Page 10: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

10

Programas com Inteiros• Problema: definir totalSales :: Int -> Int ,

função que retorna o total de vendas até um determinado dia.

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

• Para n=0: totalSales n = sales 0

• Para n>0:

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

Page 11: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

11

Programas com Inteiros

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | otherwise = totalSales (n-1) + (sales n)

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | otherwise = totalSales (n-1) + (sales n)

Main> totalSales 012Main> totalSales 250

Main> totalSales 012Main> totalSales 250

1 sales :: Int -> Int2 sales x3 | x == 0 = 124 | x == 1 = 205 | x == 2 = 186 | x == 3 = 257 | otherwise = 0

1 sales :: Int -> Int2 sales x3 | x == 0 = 124 | x == 1 = 205 | x == 2 = 186 | x == 3 = 257 | otherwise = 0

Page 12: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

12

Programas com Inteiros

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | otherwise = totalSales (n-1) + (sales n)

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | otherwise = totalSales (n-1) + (sales n)

totalSales 2= totalSales 1 + sales 2= (totalSales 0 + sales 1) + sales 2= (sales 0 + sales 1) + sales 2

totalSales 2= totalSales 1 + sales 2= (totalSales 0 + sales 1) + sales 2= (sales 0 + sales 1) + sales 2

Page 13: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

13

Programas com Inteiros

totalSales 2= totalSales 1 + sales 2= (totalSales 0 + sales 1) + sales 2= (sales 0 + sales 1) + sales 2= (12 + 20) + 18= 50

totalSales 2= totalSales 1 + sales 2= (totalSales 0 + sales 1) + sales 2= (sales 0 + sales 1) + sales 2= (12 + 20) + 18= 50

1 sales :: Int -> Int2 sales x3 | x == 0 = 124 | x == 1 = 205 | x == 2 = 186 | x == 3 = 257 | otherwise = 0

1 sales :: Int -> Int2 sales x3 | x == 0 = 124 | x == 1 = 205 | x == 2 = 186 | x == 3 = 257 | otherwise = 0

Page 14: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

14

Programas com Inteiros• Problema: definir maxSales :: Int -> Int ,

função que retorna o valor máximo (a maior venda) de unidades vendidas em um dia, em determinado período.

maxSales n = máximo entre sales 0, ..., sales n

• Para n=0: maxSales n = sales 0

• Para n>0:

maxSales n = máximo entre maxSales(n-1) e sales n

Page 15: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

15

Programas com Inteiros

12 maxSales :: Int -> Int13 maxSales n14 | n == 0 = sales 015 | maxSales(n-1) >= sales n = maxSales(n-1)16 | otherwise = sales n

12 maxSales :: Int -> Int13 maxSales n14 | n == 0 = sales 015 | maxSales(n-1) >= sales n = maxSales(n-1)16 | otherwise = sales n

maxSales 2 ?? maxSales 1 >= sales 2 ?? maxSales 0 >= sales 1 ?? sales 0 >= sales 1 ?? 12 >= 20 = 20 ?? 20 >= 18= 20

maxSales 2 ?? maxSales 1 >= sales 2 ?? maxSales 0 >= sales 1 ?? sales 0 >= sales 1 ?? 12 >= 20 = 20 ?? 20 >= 18= 20

1 sales :: Int -> Int2 sales x3 | x == 0 = 124 | x == 1 = 205 | x == 2 = 186 | x == 3 = 257 | otherwise = 0

1 sales :: Int -> Int2 sales x3 | x == 0 = 124 | x == 1 = 205 | x == 2 = 186 | x == 3 = 257 | otherwise = 0

Page 16: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

16

Programas com Inteiros

12 maxSales :: Int -> Int13 maxSales n14 | n == 0 = sales 015 | maxSales(n-1) >= sales n = maxSales(n-1)16 | otherwise = sales n

12 maxSales :: Int -> Int13 maxSales n14 | n == 0 = sales 015 | maxSales(n-1) >= sales n = maxSales(n-1)16 | otherwise = sales n

Ineficiência:maxSales(n-1) é

calculada 2 vezes!

Ineficiência:maxSales(n-1) é

calculada 2 vezes!

Page 17: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

17

Programas com Inteiros

12 maxSales :: Int -> Int13 maxSales n14 | n == 0 = sales 015 | otherwise = maxi (maxSales(n-1)) (sales n)

12 maxSales :: Int -> Int13 maxSales n14 | n == 0 = sales 015 | otherwise = maxi (maxSales(n-1)) (sales n)

• Solução alternativa (2a.):

16 maxi :: Int -> Int -> Int17 maxi m n18 | m >= n = m19 | otherwise = n

16 maxi :: Int -> Int -> Int17 maxi m n18 | m >= n = m19 | otherwise = n

Page 18: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

18

Programas com Inteiros

12 maxSales :: Int -> Int13 maxSales n14 | n == 0 = sales 015 | otherwise = maxi (maxSales(n-1)) (sales n)

12 maxSales :: Int -> Int13 maxSales n14 | n == 0 = sales 015 | otherwise = maxi (maxSales(n-1)) (sales n)

• Solução alternativa (2a.):

• Esta solução é mais clara que a primeira, destacando os casos da recursão (n == 0 e n > 0).

• É mais eficiente que a primeira, pois realiza menos cálculos.

• É elegantíssima...• Duas funções como argumentos em maxi,

Page 19: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

19

Reformulando Programas

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | otherwise = totalSales (n-1) + (sales n)

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | otherwise = totalSales (n-1) + (sales n)

totalSales -2= totalSales (-3) + sales (-2)= (totalSales (-4) + sales (-3)) + sales (-2)= ...

totalSales -2= totalSales (-3) + sales (-2)= (totalSales (-4) + sales (-3)) + sales (-2)= ...

Page 20: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

20

Reformulando Programas

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | n > 0 = totalSales (n-1) + (sales n)11 | otherwise = 0

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | n > 0 = totalSales (n-1) + (sales n)11 | otherwise = 0

Definição maisrobusta para a função!

Definição maisrobusta para a função!

Page 21: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

21

Reformulando Programas

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | n > 0 = totalSales (n-1) + (sales n)11 | otherwise = 0

8 totalSales :: Int -> Int9 totalSales n10 | n == 0 = sales 011 | n > 0 = totalSales (n-1) + (sales n)11 | otherwise = 0

8 totalSales :: Int -> Int9 totalSales n10 | n >= 0 = totalSales (n-1) + (sales n)11 | otherwise = 0

8 totalSales :: Int -> Int9 totalSales n10 | n >= 0 = totalSales (n-1) + (sales n)11 | otherwise = 0

• Ou também:

Page 22: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

22

Outros Programas

mult :: Int -> Int -> Int mult n 1 = n mult n m = n + mult n (m-1)

mult :: Int -> Int -> Int mult n 1 = n mult n m = n + mult n (m-1)

• Multiplicação entre dois números, usando a soma:

Main> abs (-13) 13Main> mult 6 7

42

Main> abs (-13) 13Main> mult 6 7

42

Alterar o programaacima para

multiplicar números negativos também !

Alterar o programaacima para

multiplicar números negativos também !

Page 23: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

23

Outros Programas

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

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

• Fatorial de n:

Main> fact 5120Main> fact 131932053504Main> fact 141278945280

Main> fact 5120Main> fact 131932053504Main> fact 141278945280

Extrapolou os limites de Int.

Extrapolou os limites de Int.

Page 24: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

24

Outros Programas

1 fact2 :: Integer -> Integer2 fact2 n3 | n <= 0 = 14 | otherwise = n * fact2 (n-1)

1 fact2 :: Integer -> Integer2 fact2 n3 | n <= 0 = 14 | otherwise = n * fact2 (n-1)

• Fatorial de n:

Main> fact 131932053504Main> fact2 136227020800Main> fact2 30265252859812191058636308480000000

Main> fact 131932053504Main> fact2 136227020800Main> fact2 30265252859812191058636308480000000

Page 25: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

25

Sintaxe• Definições e layout:

– Em Haskell, o layout de um programa é utilizado para determinar quando termina a definição de uma função e quando começa a próxima.– Uma definição termina com o primeiro elemento no mesmo nível de indentação (ou à esquerda deste).– Um cuidado: ao alinhar os programas em Haskell, as funções tem que estar na mesma coluna (limitação, eventualmente, corrigida em versões mais novas). Ex: se f1 começa na coluna 13, então todas as demais funções f2, f3 .... devem começar nesta coluna.

Page 26: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

26

Sintaxe

f x = x + x f x = x + x

Onde termina a definição da função f ?

Page 27: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

27

Sintaxe

f x = x + x f x = x + x

Até que apareça alguma definição nesse nível de

indentação, todos os elementos pertencerão à definição de f.

Page 28: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

28

Sintaxe

f x = x + x + x + 2

f x = x + x + x + 2

Page 29: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

29

Sintaxe

f x = x + x + x + 2 g x y = ...

f x = x + x + x + 2 g x y = ...

Page 30: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

30

Sintaxe

f x = x + x + x + 2 g x y = ...

f x = x + x + x + 2 g x y = ...

Page 31: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

31

Sintaxe• Definições e layout:

– Outra forma para determinar o fim de uma definição é utilizar um símbolo terminador.

– Em Haskell, o símbolo terminador é ";" . Não usual!

– Exemplo:

f x = x + x; g x y = x * y f x = x + x; g x y = x * y

Page 32: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

32

f x = x + 1

f x = x + 1

Sintaxe

• Erro comum:

• Mensagem de erro:ERROR ... Syntax error in expression (unexpected ";",

possibly due to bad layout)

Page 33: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

33

Sintaxe

• Layout recomendado:

f v1 v2 ... vn | g1 = e1 | g2 = e2 ... | otherwise = er (ou | gr = er) g x1 x2 ... Xn ...........

f v1 v2 ... vn | g1 = e1 | g2 = e2 ... | otherwise = er (ou | gr = er) g x1 x2 ... Xn ...........

Page 34: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

34

Sintaxe

• Quando expressões ou guardas são muito longas:

f v1 v2 ... vn | uma guarda muito longa que pode ocupar mais de uma linha = uma expressão muito longa que pode ocupar mais de uma linha | g2 = e2 ...

f v1 v2 ... vn | uma guarda muito longa que pode ocupar mais de uma linha = uma expressão muito longa que pode ocupar mais de uma linha | g2 = e2 ...

Page 35: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

35

Sintaxe

• Nomes em Haskell– Começam com uma letra (minúscula), seguida

(opcionalmente) por letras, dígitos, "_" e " ' ";– Começando com minúscula: funções e variáveis;– Começando com maiúscula: nomes de módulos, nomes de

tipos e contrutores de tipo (ex: True e False).

• Palavras reservadas: case class data default deriving else hiding if

import in infix infixl infixr instance interface let module of renaming then to type where

Page 36: Programação Funcional Tipos Básicos e Programas Simples em Haskell 2a. Seção de Slides

36

Sintaxe

• Comentários de linha: – Símbolo usado: --– O texto à direita é considerado comentário.

• Comentários aninhados:– Símbolos usados: {- -}– Podem se estender por várias linhas.– Agem como parêntesis, podendo existir comentários dentro

de outros comentários (aninhados).