37
CAPÍTULO 05 Listas

CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Embed Size (px)

Citation preview

Page 1: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

CAPÍTULO 05

Listas

Page 2: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Listas

• Listas são estruturas de dados fundamentais da área de programação.

• Listas em Haskell representam coleções de objetos de um determinado tipo (homogêneos).

• Para um dado tipo t, existe o tipo "lista de elementos do tipo t", designado por [t].

• Por exemplo:[1,2,3,3,0,1] :: [Int][False,False, True] :: [Bool]

são uma lista de Int e uma lista de Bool.

Page 3: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Definição

• Uma lista sempre é composta de dois segmentos, exceto quando está vazia. Tais segmentos são a cabeça (head) e o corpo (tail).

Page 4: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Definição• Uma lista com cabeça a e cauda x

é escrita no formato (a:x) .• Atenção: em (a:x)

– a é um elemento da lista -> cabeça da lista

– x é uma outra lista -> cauda da lista (que é uma outra lista ou sub-lista)

• Observação: A lista vazia “[]” está presente em qualquer lista e o último elemento aponta para esta lista “[]”.

Page 5: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Definição

• Uma lista é formada por tipos de dados homogêneos, mas pode-se utilizar como alternativa uma lista de tuplas, na qual os dados das tuplas podem ser heterogêneos.

• Restrição: todos os elementos de uma lista devem ser do mesmo tipo!

Page 6: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Casamento de padrões

• (‘a’ : [’b’, ’c’, ’d’]) == [‘a’, ’b’, ’c’, ’d’]• (‘a’ : ’b’ : ’c’ : [’d’]) == [‘a’, ’b’, ’c’, ’d’]• (‘a’ : ’b’ : ’c’ : ’d’ : []) == [‘a’, ’b’, ’c’, ’d’]• [‘a’ : [‘b’, ‘c’, ‘d’] ] == [ [‘a’, ’b’, ’c’, ’d’] ]• (‘a’ : y) == [‘a’, ’b’, ’c’, ’d’]• (‘a’ : _) == [‘a’, ’b’, ’c’, ’d’]• (‘a’ : ‘b’ : [‘c’, ‘d’]) == [x : y : z]

Page 7: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Casamento de padrões

• Alguns erros típicos de casamento de padrões em listas:

• [‘a’ : ‘b’ : [‘c’, ‘d’] ] /= [‘a’, ’b’, ’c’, ’d’]

• [ [‘a’, ’b’, ’c’, ’d’] ] /= [‘a’, ’b’, ’c’, ’d’]

• [‘a’, ’b’, [’c’], ’d’] /= [‘a’, ’b’, ’c’, ’d’]

• [ [ [‘a’] : ’b’, ’c’, ’d’] ] /= [ [‘a’, ’b’, ’c’, ’d’] ]

• [‘a’, ’b’] /= [‘a’]

Page 8: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Operadores “:” e “++"

• Atenção: os operadores “:” e “++” são diferentes!

• O operador : recebe um elemento a e uma lista x, retornando uma nova lista onde a é o primeiro elemento.

• O operador ++ recebe duas listas e retorna sua concatenação! Uma lista única.

• Para memorizar:elemento : lista = listalista ++ lista = lista

Page 9: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Exemplos

• Comprimento (tamanho) da lista: Este é um exemplo clássico sobre listas.

• 1. O comprimento de uma lista vazia é zero;

• 2. O comprimento de uma lista (a:x) é dada por 1 mais o comprimento da sublista “x” que também é uma lista:

compto [] = 0 --função 1compto (a:x) = 1+compto x --função 2

Page 10: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Exemplos

• Um “mapa de memória aproximado” da execução de “compto [1, 2, 3, 4]” é dado por:

Page 11: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Exemplos

• Obter os N primeiros termos da lista:

• primeiros 0 _ = [ ]

• primeiros _ [ ] = [ ]

• primeiros n (a:x) = a : primeiros (n-1) x

• Execução:

Page 12: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Exemplos

• Adicionar um objeto a lista:

• Esta função adiciona um objeto na lista sem repetições, isto é, caso ele já exista na lista o mesmo não é adicionado:

insere c [ ] = [c]

insere c (a:x)|c == a = a : x

|otherwise = a : insere c x

Page 13: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

A função “Observe”

• É uma das funções definidas na biblioteca Observe.hs. Destina-se a mostrar as diversas instâncias que variáveis e funções assumem durante a execução de um programa.

• Sintaxe:

import Observe

rem_ultimo [ _ ] = [ ]rem_ultimo (a:b) = observe “a” a : observe “rem_ultimo” rem_ultimo b

Page 14: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

A função “Observe”

• O resultado de uma execução da função rem_ultimo com a função observe é dado por:

Main> rem_ultimo [2, 3, 4, 5, 6, 7, 7]

>>>>>>>> Observations <<<<<<<

a

2

3

4

5

6

7

Page 15: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

A função “Observe”

rem_ultimo

{ \ (3 : 4 : 5 : 6 : 7 : _ : [ ]) -> 3 : 4 : 5 : 6 : 7 : [ ]

\ (4 : 5 : 6 : 7 : _ : [ ]) -> 4 : 5 : 6 : 7 : [ ]

\ (5 : 6 : 7 : _ : [ ]) -> 5 : 6 : 7 : [ ]

\ (6 : 7 : _ : [ ]) -> 6 : 7 : [ ]

\ (7 : _ : [ ]) -> 7 : [ ]

\ (_ : [ ]) -> [ ]

}

Page 16: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Compreensão de Lista

• A compreensão de listas é feita com um construtor de listas que utiliza conceitos e notações da teoria dos conjuntos. Por exemplo, seja o conjunto A definido por:

A = {x2 | X Є N ^ x é par}

• Este exemplo define o conjunto dos quadrados dos números pares.

• Em Haskell pode ser representado por uma lista definida da seguinte maneira:

Page 17: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Compreensão de Lista

constroi_lista = [x*x | x <- [9... 39], par x]par :: Int -> Boolpar x = mod x 2 == 0Execução:Main> par 26TrueMain> constroi_lista[100, 144, 196, 256, 324, 400, 484, 576,

676, 784, 900, 1024, 1156, 1296, 1444]

Page 18: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Strings

• As strings são formadas por uma seqüência de caracteres, um após o outro, formando uma lista em particular com o tipo caracter ou Char.

Prelude> “Oi Mundo”

“Oi Mundo”

Prelude> [‘O’, ‘i’, ‘ ’, ‘M’, ‘u’, ‘n’, ‘d’, ‘o’]

“Oi Mundo”

Prelude> (‘O’ : ‘i’ : ‘ ’ : ‘M’ : ‘u’ : [‘n’, ‘d’, ‘o’])

“Oi Mundo”

Page 19: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Conversões entre tipos

• A função show apresenta na tela strings e valores numéricos em geral.

• Em particular, a função putStr, imprime uma palavra do tipo String.

• A função read lê um conteúdo e o converte a numérico se for o caso.

• Exemplos:Prelude> “O quadrado de 7 eh: ” ++ show (7 * 7)

“O quadrado de 7 eh: 49”

Page 20: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Conversões entre tipos

Prelude> show (log 4567)“8.426611813185”

Prelude> read “77” + 380

Prelude> read “77 + 56” + 33Program error: Prelude.read: no parse

Prelude> show (read “77” + log 100)“81.6055170185”

Page 21: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Caracteres Especiais

• Alguns caracteres especiais dentro de uma string produzem efeitos na saída, quando sob a função putStr:

• \t ► Produz um espaço-padrão tabulado na saída.

• \n ► Força um salto de linha.• \\ ► Torna uma barra invertida um

caracter normal.• \’ ► Idem para aspas simples (’).• \” ► Idem para aspas duplas (”).

Page 22: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Avaliação Preguiçosa

• Um exemplo clássico de avaliação preguiçosa é exibida por:

lista_infinita :: Int -> [Int]

lista_infinita n = n : lista_infinita (n+1)

...

lista_infinita 3 = 3 : lista_infinita (3+1)

= 3 : 4 : lista_infinita (4+1)

= 3 : 4 : 5 : lista_infinita (5+1)

...

...

Page 23: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Avaliação Preguiçosa

• Esta função computa infinitos valores para uma lista de inteiros, a partir de um número passado como parâmetro. A soma não é determinada até que necessária. Como não há critério de parada, esta, cresce indefinitivamente.

Page 24: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Padrões em Haskell

• Como já visto, em Haskell há casamentos com constantes inteiras, booleanas, caracteres, strings;

• Variáveis;• Tuplas de padrões; ex: (p1,p2,...) onde p1,p2,... também são padrões.

• Listas de padrões; ex: (p1:p2) onde p1 e p2 também são padrões.

• O padrão “_” (o “underscore”);• Construtores de padrões: ( .. : ..), case

Page 25: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Padrões em Haskell

• Quando um argumento a casa com um padrão p?– se p é uma constante e p=a; Ex: 7 == 7– se p é uma variável x, sendo que a será associado a x;– se p é uma tupla (p1,p2,...), a=(a1,a2,...) e cada

componente de a casa com o respectivo componente de p.Ex: (3,1,2) == (3,1,2)

True – se p é uma lista (p1:p2), a é uma lista não vazia e a

cabeça de a casa com p1 e sua cauda casa com p2.– Ex: (1 , 2 , [4 .. 40] ) == (1 , 2, [4 .. 40])

True

Page 26: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Padrões em Haskell

Quanto ao “_” ?{- inicio: uma nova lista, sem o último elemento -} inicio :: [a] -> [a] inicio [ _ ] = [] inicio (x:xs) = observe "x" x : observe "inicio" inicio xs

inicio [1 .. 7][1,2,3,4,5,6]

Não esquecer:

module Listas whereimport Observe

Page 27: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Padrões em Haskellinicio [1 .. 7][1,2,3,4,5,6]

>>>>>>> Observations <<<<<<

x 1 2 3 4 5 6

inicio { \ (2 : 3 : 4 : 5 : 6 : 7 : []) -> 2 : 3 : 4 : 5 : 6 : [] , \ (3 : 4 : 5 : 6 : 7 : []) -> 3 : 4 : 5 : 6 : [] , \ (4 : 5 : 6 : 7 : []) -> 4 : 5 : 6 : [] , \ (5 : 6 : 7 : []) -> 5 : 6 : [] , \ (6 : 7 : []) -> 6 : [] , \ (7 : []) -> [] }

Page 28: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Padrões em Haskell

• Restrição importante: não é permitido usar um mesmo nome mais de uma vez dentro do mesmo padrão!

• Exemplo:

ERRO – variável repetida em padrão!!! (Repeated variable "x" in

pattern)

• Solução :

1 .2 .3 .

1 .2 .3 .

func :: Int -> Int -> Boolfunc x x = Truefunc x y = False

1 .2 .3 .

1 .2 .3 .

func :: Int -> Int -> Boolfunc x y | x == y = Truefunc x y = False

Page 29: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Aplicação: BD para Biblioteca

• Uma biblioteca usa um banco de dados para manter um registro dos livros emprestados aos clientes.

• Pessoas e livros serão representados por Strings.

• O BD será uma lista de pares (Pessoa,Livro).

• Se um par (p,b) estiver no BD, isso significa que o cliente p pegou um exemplar do livro b emprestado.

Page 30: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Tipos

• Exemplo de BD:

exBD = [ ("Alice", "Senhor dos Anéis"), ("Ana", "Windows 3.1"), ("Alice", "Excel para Leigos"), ("Ricardo", "Senhor dos Anéis") ]

1 .2 .3 .

1 .2 .3 .

type Pessoa = Stringtype Livro = Stringtype BancoDados = [ (Pessoa, Livro) ]

Page 31: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Funções de Pesquisa

• As funções de pesquisa em BD recebem como entrada um BD, uma pessoa ou livro, e retornam o resultado da pesquisa.

• Exemplos:– Dada uma pessoa, encontrar os livros emprestados por

ela.– Dado um livro (pode ter mais de uma cópia), listar as

pessoas que estão com o mesmo emprestado.– Dado um livro, descobrir se está emprestado.– Dada uma pessoa, calcular o número de livros que ela tem

emprestados no momento.livros :: BancoDados -> Pessoa -> [Livro]clientes :: BancoDados -> Livro -> [Pessoa]emprestado :: BancoDados -> Livro -> BoolnumEmprest :: Bancodados -> Pessoa -> Int

Page 32: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Funções de Atualização

• As funções de atualização recebem como entrada um BD e retornam um novo BD, resultado de uma operação.

• Exemplos:– Emprestar um livro a um cliente.– Devolver um livro emprestado.

fazEmprest :: BancoDados -> Pessoa -> Livro -> BancoDadosretEmprest :: BancoDados -> Pessoa -> Livro -> BancoDados

Page 33: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Definindo as funções de Pesquisa

• Definir a função: livros :: BancoDados -> Pessoa -> [Livro]

• As funções clientes, emprestado, numEmprest podem ser definidas de forma semelhante.

1 .2 .3 .4 .5 .

1 .2 .3 .4 .5 .

livros :: BancoDados -> Pessoa -> [Livro]livros [] p = []livros ((n,b) : resto) p | p == n = b : livros resto p | otherwise = livros resto p

Page 34: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Definindo as funções de Atualização

• Definir a função: fazEmprest :: BancoDados -> Pessoa ->

Livro -> BancoDados

• Basta adicionar um novo par ao banco de dados (pode haver repetições).

• Pesquisar o BD e remover a primeira ocorrência do par (pes,liv).

• Se não existir esse par no BD, é caracterizada uma situação de erro!

1 .2 .3 .

1 .2 .3 .

fazEmprest:: BancoDados -> Pessoa -> Livro -> BancoDadosfazEmprest db p b = (p,b) : db

Page 35: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Definindo as funções de Atualização

retEmprest:: BancoDados -> Pessoa -> Livro -> BancoDados

retEmprest ((p,b) : resto) pes liv | p == pes && b == liv = resto | otherwise = (p,b) : retEmprest resto pes liv

retEmprest [] pes liv = error ("falha em retEmprest:" ++ pes ++ " " ++ liv)

Cancela apenas a primeira ocorrência do par.Cancela apenas a primeira ocorrência do par.

Page 36: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Definindo as funções de Atualização

• Definição alternativa, cancelando todas as ocorrências do par:

retEmprest:: BancoDados -> Pessoa -> Livro -> BancoDados

retEmprest ((p,b) : resto) pes liv | p==pes && b==liv = retEmprest resto pes liv | otherwise = (p,b) : retEmprest resto pes liv

retEmprest [] pes liv = []

Page 37: CAPÍTULO 05 Listas. Listas são estruturas de dados fundamentais da área de programação. Listas em Haskell representam coleções de objetos de um determinado

Conclusão

• Listas e suas funções são TAD’s do Haskell

• O poliformismo de tipos é evidenciado. Aplica-se uma função igualmente a todos objetos da lista. Uma função é reusada, sobre vários tipos!

• Uma função serve há vários tipos de listas.• Há muitas funções prontas (“built-in”), já

definidas pelo ambiente.