View
223
Download
0
Category
Preview:
Citation preview
1/104
Programação Funcional
Aula 6
Listas
José Romildo Malaquias
Departamento de ComputaçãoUniversidade Federal de Ouro Preto
2011.2
2/104
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
3/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
4/104
Listas
I Lista é uma seqüência de elementos de um mesmo tipo.
I [a] é o tipo das listas cujos elementos são do tipo aI Estruturalmente a forma de uma lista pode ser:
lista vazianenhum elemento na seqüênciaconstrutor de dado: (constante)
[] :: [a]
lista não vaziaformada por dois componentes:cabeça: o primeiro elemento da listacauda: lista de todos os demais elementos, a partir do segundoconstrutor de dado: (dois argumentos)
infixr 5 :(:) :: a -> [a] -> [a]
O primeiro argumento é a cabeça da lista.O segundo argumento é a cauda da lista.
5/104
Exemplos de listas
[]
I seqüência vazia (nenhum elemento)
I não tem cabeça e nem cauda
I tipo: [a]
I é um valor polimórfico, pois pertence a todos os tipos lista
6/104
Exemplos de listas (cont.)
False : []
I seqüência: False
I cabeça: False
I cauda: []
I tipo: [Bool]
7/104
Exemplos de listas (cont.)
’a’ : (’b’ : [])
I seqüência: ’a’, ’b’
I cabeça: ’a’
I cauda: ’b’ : []
I tipo: [Char]
8/104
Exemplos de listas (cont.)
15 : (9 : (42 : []))
I seqüência: 15, 9, 42
I cabeça: 15
I cauda: 9 : (42 : [])
I tipo: Num a => [a]
9/104
Exemplos de listas (cont.)
15 : (9.45 : (15 : (0 : [])))
I seqüência: 15, 9.45, 15, 0
I cabeça: 15
I cauda: 9.45 : (15 : (0 : []))
I tipo: Fractional a => [a]
10/104
Exemplos de listas (cont.)
15 : (’H’ : (False : []))não é uma expressão válida, uma vez que todos os elementos de umalista devem ser de um mesmo tipo.
11/104
Notações de listas
I O construtor constante [] denota a lista vazia.
I O construtor : constrói uma lista não vazia a partir da cabeça eda cauda.
I : é um operador binário infixo com precedência 5 eassociatividade à direita.
I Isto significa que os parênteses no segundo argumentogeralmente são desnecessários.
I Exemplo: o valor100 : 200 : 300 : 400 : []
é idêntido a100 : (200 : (300 : (400 : [])))
12/104
Notações de listas (cont.)
I Uma lista finita pode ser denotada escrevendo os seuselementos entre colchetes e separados por vírgula:[ exp1, ..., expn ]
I Esta é uma notação simplificada para listas finitas, sendoequivalente aexp1 : ... : expn : []
13/104
Notações de listas (cont.)
I Exemplo:A lista de 6 números[10, 20, 30, 40, 50, 60]
é apenas uma abreviação sintática para10 : 20 : 30 : 40 : 50 : 60 : []
14/104
Notações de listas (cont.)
I Exemplo:A lista[[]]
que é uma abreviação para[] : []
é a lista unitária cujo único elemento é a lista vazia. O seu tipo é[[a]].
15/104
Exercícios
Exercício 1
Dê um exemplo de uma expressão que contenha duas ocorrências dalista vazia, sendo a primeira ocorrência do tipo [Bool] e a segundado tipo [Char].
16/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
17/104
Strings
I Em Haskell strings (cadeias de caracteres) são simplesmentelistas de caracteres.
I O tipo String é um sinônimo para [Char] .
I Existe uma notação especial para constantes strings: aseqüência de caracteres é escrita entre aspas " .
I Exemplos:
A string "UFOP" é apenas uma sintaxe conveniente para a lista decaracteres [’U’,’F’,’O’,’P’]A string vazia "" é o mesmo que [], a lista vazia, do tipo [Char].
18/104
Strings (cont.)
I Códigos de escape podem ser usados em constantes caractere constantes strings para representar alguns caracteres.
I Exemplos:’\n’’\\’"bom\ndia\nbrasil""abcd\tEFG""\"aspas\" dentro da string""tabulador:\tou\^Iou\9."
19/104
Strings (cont.)
I Códigos de escape de 1 caracter:
Escape Unicode Character\0 U+0000 null character\a U+0007 alert\b U+0008 backspace\f U+000C form feed\n U+000A newline (line feed)\r U+000D carriage return\t U+0009 horizontal tab\v U+000B vertical tab\" U+0022 double quote\& n/a no character\’ U+0027 single quote\\ U+005C backslash
20/104
Strings (cont.)
I Códigos de controle:
Escape Escape Unicode Meaning\NUL \^@ U+0000 null character\SOH \^A U+0001 start of heading\STX \^B U+0002 start of text\ETX \^C U+0003 end of text\EOT \^D U+0004 end of transmission\ENQ \^E U+0005 enquiry\ACK \^F U+0006 acknowledge\BEL \^G U+0007 bell\BS \^H U+0008 backspace\HT \^I U+0009 horizontal tab\LF \^J U+000A line feed (newline)\VT \^K U+000B vertical tab\FF \^L U+000C form feed\CR \^M U+000D carriage return
21/104
Strings (cont.)
\SO \^N U+000E shift out\SI \^O U+000F shift in\DLE \^P U+0010 data link escape\DC1 \^Q U+0011 device control 1\DC2 \^R U+0012 device control 2\DC3 \^S U+0013 device control 3\DC4 \^T U+0014 device control 4\NAK \^U U+0015 negative acknowledge\SYN \^V U+0016 synchronous idle\ETB \^W U+0017 end of transmission block\CAN \^X U+0018 cancel\EM \^Y U+0019 end of medium\SUB \^Z U+001A substitute\ESC \^[ U+001B escape\FS \^\ U+001C file separator\GS \^] U+001D group separator\RS \^^ U+001E record separator
23/104
Strings (cont.)
I Códigos de escape numéricos:
\decimal código decimal\o octal código octal\x hexa código hexadecimal
Exemplos:\1234\xbeef\o1234O valor numérico máximo é \1114111, que também pode serescrito \x10ffff ou \o4177777.
24/104
Strings (cont.)
I Seqüência de escape vazia:\&
Literais string podem conter a seqüência de esccape vazia,escrita \&.Ela não é um caracter real, mas serve para separar umaseqüência de escape numérica de um dígito decimal que vemlogo em seguida.Exemplo:A string "\130\&12" é formada pelos caracteres ’\130’, ’1’ e’2’.Já a string "\13012" é formada apenas pelo caracter ’\13012’.
25/104
Strings (cont.)
I Seqüência de escape gap:\brancos\
Esta seqüência pode aparecer em literais strings.É formada por uma seqüência de caracteres brancos (espaços,mudanças de linha, tabulações, ...) delimitada pelo caracter \.Ela não reprsenta nenhum caracter e é ignorada.É útil para escrever um literal string em várias linhas.Exemplo: A string"uma longa \
\string, escrita\\ em muitas linhas"
é a idêntica a"uma longa string, escrita em muitas linhas"
26/104
Instância de classes
I Tipos listas são instâncias de várias classes:instance Eq a => Eq [a]instance Ord a => Ord [a]instance Read a => Read [a]instance Show a => Show [a]
I Duas listas são iguais se e somente se os seus elementoscorrespondentes são iguais.
I A comparação de listas é lexicográfica (da mesma maneira quepalavras são organizadas em um dicionário).
27/104
Instância de classes (cont.)
I Exemplos:[1,2,3,4,5] == [1,2,3,4,5] True[1,2] == [1,2,3] False"Maria" /= "maria" True"elegante" <= "elefante" False[1,2,3] > [1,2] Truecompare "Abracadabra" "Zebra" LTshow [1,2,3,4] "[1,2,3,4]"show "Bom dia!" "\"Bom dia!\""read "[6,0,32]" :: [Int] [6,0,32]read "[’f’,’i’,’m’]" :: String "fim"read "\"fim\"" :: String "fim"
28/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
30/104
Seqüências aritméticas (cont.)
[ exp1, exp2 .. exp3 ]
I É a seqüência aritmética que começa com exp1, continua comexp2 e cujos elementos não ultrapassam exp3.
I Para tipos numéricos, a razão da progressão é exp2− exp1.I Exemplos:
[4,6..14] [4,6,8,10,12,14][5,10..44] [5,10,15,20,25,30,35,40][18,15..0] [18,15,12,9,6,3,0][4.0,4.4..5.2] [4.0,4.4,4.800000000000001,5.200000000000001][’m’,’o’..’x’] "moqsuw"[’0’,’2’..’9’] "02468"[’m’,’o’..’a’] ""
31/104
Seqüências aritméticas (cont.)
[ exp1 .. exp2 ]
I É a seqüência aritmética que começa com exp1 e cujoselementos não ultrapassam exp2.
I Para tipos numéricos, a razão da progressão é 1.I Exemplos:
[5..10] [5,6,7,8,9,10][7..19] [7,8,9,10,11,12,13,14,15,16,17,18,19][7..5] [][’M’..’P’] "MNOP"[False .. True] [False,True]
32/104
Seqüências aritméticas (cont.)
[ exp1, exp2 .. ]
I É a seqüência aritmética que começa com exp1 e cujo segundoelemento é exp2.
I Para tipos numéricos, a razão da progressão é exp2− exp1.
I Pode ser infinita.I Exemplos:
[5,7..] [5,7,9,11,13,15,17,... (seqüência infinita)[0,6..] [0,6,12,18,24,30,36,... (seqüência infinita)[7,2..] [7,2,-3,-8,-13,-18,... (seqüência infinita)[9,9..] [9,9,9,9,9,9,9,9,9,... (seqüência infinita)
33/104
Seqüências aritméticas (cont.)
[ exp1 .. ]
I É a seqüência aritmética que começa com exp1.
I Para tipos numéricos, a razão da progressão é 1.
I Pode ser infinita.I Exemplos:
[5 ..] [5,6,7,8,9,10,11,12,13,... (seqüência infinita)[3 ..] [3,4,5,6,7,8,9,10,11,12,... (seqüência infinita)[1.1 ..] [1.1,2.1,3.1,4.1,5.1,6.1,... (seqüência infinita)[LT ..] [LT,EQ,GT]
[5..] :: (Enum a, Num a) => [a][’B’..] :: [Char]
34/104
Seqüências aritméticas (cont.)
I A notação de lista para seqüências aritméticas é simplesmenteuma abreviação sintática para aplicações de métodos da classeEnum:[ a, b .. c ] ≡ enumFromThenTo a b c[ a .. b ] ≡ enumFromTo a b[ a, b .. ] ≡ enumFromThen a b[ a .. ] ≡ enumFrom a
I Exemplo:[10,15..44] [10,15,20,25,30,35,40]enumFromThenTo 10 15 44 [10,15,20,25,30,35,40]
I Portanto seqüências aritméticas só podem ser usadas para listasde elementos de um tipo que seja instância da classe Enum.
35/104
Seqüências aritméticas (cont.)
I A classe Enum:class Enum a where
succ :: a -> apred :: a -> atoEnum :: Int -> afromEnum :: a -> IntenumFrom :: a -> [a]enumFromThen :: a -> a -> [a]enumFromTo :: a -> a -> [a]enumFromThenTo :: a -> a -> a -> [a]
instance Enum Intinstance Enum Integerinstance Enum Floatinstance Enum Doubleinstance Enum Charinstance Enum Boolinstance Enum Orderinginstance Enum ()
36/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
37/104
Casamento de padrão com listas
I Casamento de padrão é a operação básica de Haskell paradecompor valores estruturados.
I Para cada construtor de dados existe uma forma de padrãocorrespondente.
38/104
Casamento de padrão com listas (cont.)
I Estruturalmente uma lista pode ser vazia ou não vazia:padrão lista vazia[]
é um padrão constanteo casamento sucede se e somente se o valor for a lista vazia
padrão lista não vazia
pad1 : pad2
é formado por dois padrões pad1 e pad2o casamento sucede se e somente se o valor for uma lista nãovazia cuja cabeça casa com pad1 e cuja cauda casa com pad2
39/104
Casamento de padrão com listas (cont.)
I Exemplo:O padrão [] casa somente com a lista vazia.
padrão valor casamento variáveis[] [] sucede[] [1,2,3] falha
40/104
Casamento de padrão com listas (cont.)
I Exemplo:O padrão x:xs casa com qualquer lista não vazia, associandoas variáveis x e xs com a cabeça e a cauda da lista,respectivamente.
padrão valor casamento variáveisx:xs [] falhax:xs [1,2,3] sucede x 7→ 1, xs 7→ [2,3]x:xs [’A’] sucede x 7→ ’A’, xs 7→ []
41/104
Casamento de padrão com listas (cont.)
I Exemplo:O padrão x:y:_ casa com qualquer lista que tenha pelo menosdois elementos, associando as variáveis x e y ao primeiro esegundo elementos da lista, respectivamente.
padrão valor casamento variáveisx:y:_ [] falhax:y:_ ["ana"] falhax:y:_ [1,2] sucede x 7→ 1, y 7→ 2x:y:_ [1,2,3] sucede x 7→ 1, y 7→ 2
42/104
Casamento de padrão com listas (cont.)
I Exemplo:O padrão x:_:z:[] casa com qualquer lista que tenhaexatamente três elementos, associando as variáveis x e z aoprimeiro e terceiro elementos da lista, respectivamente.
padrão valor casamento variáveisx:_:z:[] [] falhax:_:z:[] ["ana"] falhax:_:z:[] [1,2,3] sucede x 7→ 1, z 7→ 3x:_:z:[] [1,2,3,4,5] falha
43/104
Casamento de padrão com listas (cont.)
I Exemplo:O padrão 0:a:_ casa com qualquer lista de números que tenhapelo menos dois elementos, sendo o primeiro igual a zero,associando a variável a ao segundo elemento da lista.
padrão valor casamento variáveis0:a:_ [] falha0:a:_ [0] falha0:a:_ [0,2,3] sucede a 7→ 20:a:_ [0,10,6,3] sucede a 7→ 100:a:_ [7,0,8] falha
44/104
Casamento de padrão com listas (cont.)
I Exemplo:O padrão (m,_):_ casa com qualquer lista de pares não vazia,associando a variável m ao primeiro componente do par que é oprimeiro elemento da lista.
padrão valor casamento variáveis(m,_):_ [] falha(m,_):_ [("fim",True)] sucede m 7→ "fim"(m,_):_ [(10,’M’),(20,’F’)] sucede m 7→ 10
45/104
Casamento de padrão com listas (cont.)
I A forma[ padrao1, . . ., padraon ]
é uma abreviação sintática parapadrao1 : . . . : padraon : []
cujo casamento sucede somente se a lista tiver exatamente nelementos.
46/104
Casamento de padrão com listas (cont.)
I Exemplo:O padrão [1,alfa] casa com qualquer lista de dois númerosque começa com 1, associando a variável alfa ao segundoelemento da lista.
padrão valor casamento variáveis[1,alfa] [] falha[1,alfa] [1] falha[1,alfa] [1,5] sucede alfa 7→ 5[1,alfa] [9,5] falha[1,alfa] [1,2,3] falha
47/104
Casamento de padrão com listas (cont.)
I Exemplo:A expressãocase tail [10] of
[] -> "vazia"_ -> "nao vazia"
resulta em "vazia", pois o valor da expressão tail [10] casacom o padrão para lista vazia [].
48/104
Casamento de padrão com listas (cont.)
I Exemplo:A expressãocase [10,20,30,40] of
[] -> "lista vazia"x:xs -> "cabeca: " ++ show x ++ " cauda: " ++ show xs
resulta em "cabeca: 10 cauda: [20,30,40]", pois a lista[10,20,30,40] casa com o padrão para lista não vazia x:xs,associando x com 10 e xs com [20,30,40].
49/104
Casamento de padrão com listas (cont.)
I Exemplo:A expressãocase [10..20] of
x:y:z:_ -> x + y + z_ -> 0
resulta em 33, pois a lista [10..20] casa com o padrãox:y:z:_, associando x com 10, y com 11 e z com 12.
50/104
Casamento de padrão com listas (cont.)
I Exemplo:A expressãocase [10,20] of
x:y:z:_ -> x + y + z_ -> 0
resulta em 0, pois a lista [10,20] não casa com o primeiropadrão x:y:z:_, mas casa com o segundo _.Observe que o primeiro padrão casa somente com listas quetenham pelo menos três elementos.
51/104
Casamento de padrão com listas (cont.)
I Exemplo:A expressãocase [10,20,30] of
[x1,_,x3] -> x1 + x3_ -> 0
resulta em 40, pois a lista [10,20,30] casa com o primeiropadrão [x1,_,x3].Observe que este padrão casa somente com listas que tenhamexatamente três elementos.
52/104
Casamento de padrão com listas (cont.)
I Exemplo:A expressãocase [100,20,3] of
a:b:xs | a > b -> b:a:xs| a = b -> a:xs
xs -> xsresulta em [20,100,3], pois a lista [100,20,3] casa com oprimeiro padrão a:b:xs e o primeiro elemento é maior do que osegundo.
53/104
Exercícios
Exercício 2
Defina uma função usando casamento de padrão que retorna osucessor do primeiro elemento de uma lista, se houver, e zero casocontrário.
Exercício 3
Usando casamento de padrão, defina uma função que retorna a somados dois primeiros elementos de uma lista se a lista tiver pelo menosdois elementos, a cabeça da lista se ela contiver apenas umelemento, e zero caso contrário.
Exercício 4
Resolva os exercícios 2 e 3 usando funções da biblioteca ao invés decasamento de padrão.
54/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
55/104
Operações com listas
I As listas são muito importantes na programação funcional.
I Serão apresentadas as operações principais com listas.
56/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
57/104
Operações com listas: null
I null retorna True se o seu argumento é a lista vazia ([]) e Falsecaso contrário.
I Exemplos:null [] Truenull [1,2,3,4,5] Falsenull "" Truenull "FIM" False
null :: [a] -> Boolnull [] = Truenull _ = False
58/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
59/104
Operações com listas: head
I head seleciona o primeiro elemento de uma lista não vazia.
I Exemplos:head [10,20,30,40,50] 10head "FIM" ’F’head [] errohead "" erro
head :: [a] -> ahead (x:_) = x
60/104
Operações com listas: tail
I tail seleciona a cauda de uma lista não vazia, isto é, todos oselementos exceto o primeiro.
I Exemplos:tail [10,20,30,40,50] [20,30,40,50]tail "Aroma" "roma"tail [] errotail "" erro
tail :: [a] -> atail (_:xs) = xs
61/104
Operações com listas: init
I init seleciona todos os elementos de uma lista não vazia,exceto o último elemento.
I Exemplos:init [15] []init [True,False] [True]init [1,2,3,4,5] [1,2,3,4]init "Brasil" "Brasi"init [] erro
init :: [a] -> [a]init [_] = []init (x:xs) = x : init xs
62/104
Operações com listas: last
I last seleciona o último elemento de uma lista não vazia.
I Exemplos:last [15] 15last [True,False] Falselast [1,2,3,4,5] 5last "Brasil" ’l’last [] erro
last :: [a] -> alast [x] = xlast (_:xs) = last xs
63/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
64/104
Operações com listas: elem
I elem recebe um valor e uma lista e retorna True se e somentese o valor é um elemento da lista.
I Exemplos:elem 5 [] Falseelem 5 [5] Trueelem 5 [4,5] Trueelem ’d’ "Pedro" True8 ‘elem‘ [2,4,6,8,10] True’#’ ‘elem‘ "Pedro" False
infixl 4 ‘elem‘elem :: Eq a => a -> [a] -> Boolelem _ [] = Falseelem x (y:ys) = x == y || elem x ys
65/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
66/104
Operações com listas: length
I length retorna o número de elementos de uma lista finita.
I Exemplos:length [] 0length [15] 1length [div 2 0, mod 3 0] 2length [1,2,3,4,5] 5length "Brasil" 6
length :: [a] -> Intlength [] = 0length (_:xs) = 1 + length xs
67/104
Operações com listas: (!!)
I (!!) recebe uma lista e um número inteiro e retorna o elementoda lista cuja posição é dada pelo número.
I A posição do primeiro elemento é zero.
I A posição do último elemento é o tamanho da lista menos um.
I Se a posição for inválida ocorre um erro.
I Exemplos:[1,2,3,4,5] !! 0 1[1,2,3,4,5] !! 1 2"Brasil" !! 3 ’s’[35,46] !! 8 erro[35,46] !! (-2) erro
infixl 9 !!(!!) :: [a] -> Int -> a(x:_) !! 0 = x(_:xs) !! n = xs !! (n-1)
68/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
69/104
Operações com listas: take
I take recebe um número inteiro n e uma lista xs e retorna oprefixo de tamanho n da lista xs.
I Exemplos:take 5 "Hello World!" "Hello"take 3 [1,2,3,4,5] [1,2,3]take 3 [1,2] [1,2]take 3 [] []take (-9) [1,2] []take 0 [1,2] []
take :: Int -> [a] -> [a]take n _ | n <= 0 = []take _ [] = []take n (x:xs) = x : take (n-1) xs
70/104
Operações com listas: drop
I drop recebe um número inteiro n e uma lista xs e retorna o sufixoda lista xs após os n primeiros elementos.
I Exemplos:drop 6 "Hello World!" "World!"drop 3 [1,2,3,4,5] [4,5]drop 3 [1,2] []drop 3 [] []drop (-9) [1,2] [1,2]drop 0 [1,2] [1,2]
drop :: Int -> [a] -> [a]drop n xs | n <= 0 = xsdrop _ [] = []drop n (_:xs) = drop (n-1) xs
71/104
Operações com listas: splitAt
I splitAt recebe um número inteiro n e uma lista xs e retorna umpar onde o primeiro elemento é um prefixo de tamanho n de xs eo segundo elemento é o resto da lista.
I Exemplos:splitAt 6 "Hello World!" ("Hello ","World!")splitAt 3 [1,2,3,4,5] ([1,2,3],[4,5])splitAt 1 [1,2,3] ([1],[2,3])splitAt 3 [1,2,3] ([1,2,3],[])splitAt 4 [1,2,3] ([1,2,3],[])splitAt 0 [1,2,3] ([],[1,2,3])splitAt (-9) [1,2,3] ([],[1,2,3])
72/104
Operações com listas: splitAt (cont.)
splitAt :: Int -> [a] -> ([a],[a])splitAt n xs | n <= 0 = ([],xs)splitAt _ [] = ([],[])splitAt n (x:xs) = (x:xs’,xs”)
where(xs’,xs”) = splitAt (n-1) xs
73/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
74/104
Operações com listas: (++)
I (++) concatena duas listas.
I Exemplos:[] ++ [20,10] [20,10][4] ++ [20,10] [4,20,10][1,2,3,4,5] ++ [20,10] [1,2,3,4,5,20,10]"ana" ++ " carolina" "ana carolina"[(10,True),(5,False)] ++ [] [(10,True),(5,False)][1,2] ++ [] ++ [1] ++ [0,3] [1,2,1,0,3]
infixr 5 ++(++) :: [a] -> [a] -> [a][] ++ ys = ys(x:xs) ++ ys = x : (xs ++ ys)
75/104
Operações com listas: concat
I concat aplicada a uma lista de listas, concatena as listas emuma única lista
I Exemplos:concat [] []concat [[1,2,3]] [1,2,3]concat [[1,2,3], [4]] [1,2,3,4]concat [[1,2,3], [4], [], [5,6,7,8]] [1,2,3,4,5,6,7,8]concat ["we"," ","like"," ","lists"] "we like lists"
concat :: [[a]] -> [a]concat [] = []concat (xs:xss) = xs ++ concat xss
76/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
77/104
Operações com listas: reverse
I reverse recebe uma lista finita e retorna uma lista com osmesmos elementos, porém em ordem reversa.
I Exemplos:reverse [] []reverse [1] [1]reverse [1,2] [2,1]reverse [1,2,3] [3,2,1]reverse [1,2,3,4,5] [5,4,3,2,1]reverse "ROMA" "AMOR"
reverse :: [a] -> [a]reverse [] = []reverse (x:xs) = reverse xs ++ [x]
78/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
79/104
Operações com listas: zip
I zip recebe duas listas e retorna a lista dos pares formados peloselementos correspondentes da primeira e da segunda lista.
I Se as listas forem de tamanhos diferentes, o tamanho doresultado é o menor tamanho.
I Exemplos:zip [] [] []zip [1,2,3] [] []zip [] [1,2,3] []zip [True] [1] [(True,1)]zip [1,2] ["ana","pedro"] [(1,"ana"),(2,"pedro")]zip [1,2,3] "ABC" [(1,’A’),(2,’B’),(3,’C’)]zip [1,2,3,4,5] [0.5,0.6] [(1,0.5),(2,0.6)]zip [1,2,3] "BRASIL" [(1,’B’),(2,’R’),(3,’A’)]
zip :: [a] -> [b] -> [(a, b)]zip (x:xs) (y:ys) = (x,y) : zip xs yszip _ _ = []
80/104
Operações com listas: zipWith
I zipWith recebe uma função binária e duas listas e retorna a listaformada pelos resultados da aplicação da função aos elementoscorrespondentes da listas dadas.
I Se as listas forem de tamanhos diferentes, o tamanho doresultado é o menor tamanho.
I Exemplos:zipWith (+) [] [] []zipWith (+) [1,2,3,4,5] [3,3,4,1,5] [4,5,7,5,10]zipWith (++) ["AB","cde"] ["?","123"] ["AB?","cd123"]zipWith (^) [5,6,7,8] [2,3,4,5] [25,216,2401,32768]zipWith (*) [5,6,7,8] [2,3] [10,18]
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]zipWith f (x:xs) (y:ys) = f x y : zipWith f xs yszipWith _ _ _ = []
81/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
82/104
Operações com listas: map
I map recebe uma função e uma lista e retorna a lista formada pelaaplicação da função em cada elemento da lista dada.
I Exemplos:map sqrt [0,1,4,9] [0.0,1.0,2.0,3.0]map succ "HAL" "IBM"map head ["bom","dia","turma"] "bdt"map (<3) [1,2,3] [True,True,False]map (+2) [2,5,6,0] [4,7,8,2]map (\x -> 2*x+1) [2,5,6,0] [5,11,13,1]
map :: (a -> b) -> [a] -> [b]map _ [] = []map f (x:xs) = f x : map f xs
83/104
Operações com listas: filter
I filter recebe uma função f e uma lista xs e retorna a listaformada pelos elementos de xs para os quais a função f retornaTrue.
I Exemplos:filter even [0,1,4,9,10,11,15] [0,4,10]filter (<10) [0,1,4,9,10,11,15] [0,1,4,9]filter (not . null) ["abc","","d"] ["abc","d"]
filter :: (a -> Bool) -> [a] -> [a]filter _ [] = []filter f (x:xs)
| f x = x : filter f xs| otherwise = filter f xs
84/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
85/104
Operações com listas: foldl
I foldl reduz uma lista, usando uma função binária e um valorinicial, de forma associativa à esquerda.
I foldl (⊕) e [x0,x1,...,xn−1]≡(...((e ⊕ x0) ⊕ x1) ...) ⊕ xn−1
I Exemplos:foldl (+) 0 [] 0foldl (+) 0 [1] 1foldl (+) 0 [1,2] 3foldl (+) 0 [1,2,4] 7foldl (*) 1 [5,2,4,10] 400foldl (&&) True [2>0,even 6,odd 5,null []] Truefoldl (||) False [2>3,even 6,odd 5,null []] Truefoldl (\a x -> 2*a+x) 0 [1,2,3,4,5] 57
86/104
Operações com listas: foldl (cont.)
foldl :: (a -> b -> a) -> a -> [b] -> afoldl f z [] = zfoldl f z (x:xs) = foldl f (f z x) xs
87/104
Operações com listas: foldr
I foldr reduz uma lista, usando uma função binária e um valorinicial, de forma associativa à direita.
I foldr (⊕) e [x0,...,xn−2,xn−1]≡x0 ⊕ (... (xn−2 ⊕ (xn−1 ⊕ e)) ...)
I Exemplos:foldr (+) 0 [] 0foldr (+) 0 [1] 1foldr (+) 0 [1,2] 3foldr (+) 0 [1,2,4] 7foldr (*) 1 [5,2,4,10] 400foldr (&&) True [2>0,even 6,odd 5,null []] Truefoldr (||) False [2>3,even 6,odd 5,null []] Truefoldr (\x a -> 2*a+x) 0 [1,2,3,4,5] 129
88/104
Operações com listas: foldr (cont.)
foldr :: (a -> b -> b) -> b -> [a] -> bfoldr f z [] = zfoldr f z (x:xs) = f x (foldr f z xs)
89/104
Operações com listas: foldl1
I foldl1 reduz uma lista não vazia usando uma função binária, deforma associativa à esquerda.
I foldl1 é uma variante de foldl que não tem valor inicial, eportanto deve ser aplicada a listas não-vazias.
I Exemplos:foldl1 (+) [] errofoldl1 (+) [1] 1foldl1 (+) [1,2,4] 7foldl1 (*) [5,2,4,10] 400foldl1 (&&) [2>0,even 6,odd 5,null []] Truefoldl1 max [1,8,6,10,-48,5] 10
foldl1 :: (a -> a -> a) -> [a] -> afoldl1 f (x:xs) = foldl f x xs
90/104
Operações com listas: foldr1
I foldr1 reduz uma lista não vazia usando uma função binária, deforma associativa à esquerda.
I foldr1 é uma variante de foldr que não tem valor inicial, eportanto deve ser aplicada a listas não-vazias.
I Exemplos:foldr1 (+) [] errofoldr1 (+) [1] 1foldr1 (+) [1,2,4] 7foldr1 (*) [5,2,4,10] 400foldr1 (&&) [2>0,even 6,odd 5,null []] Truefoldr1 max [1,8,6,10,-48,5] 10
foldr1 :: (a -> a -> a) -> [a] -> afoldr1 _ [x] = xfoldr1 f (x:xs) = f x (foldr1 f xs)
91/104
Exercícios
Exercício 5
Defina a função recursivaproduct :: Num a => [a] -> a
que retorna o produto de uma lista de números.
Exercício 6
Defina as funções recursivasand :: [Bool] -> Boolor :: [Bool] -> Bool
que retornam respectivamente a conjunção e a disjunção de uma listade valoresl lógicos.
92/104
Layout
1 Listas
2 Strings
3 Seqüências aritméticas
4 Casamento de padrão com listas
5 Operações com listasnullhead e tail, init e lastelemlength e (!!)take, drop e splitAt(++) e concatreversezip e zipWithmap e filterfoldl e foldr, foldl1 e foldr1
6 List comprehension
93/104
List comprehension
I Em Matemática, a notação de compreensão pode ser usada paraconstruir novos conjuntos a partir de conjuntos já conhecidos.
I Exemplo:{x2|x ∈ [1...5]}
é o conjunto {1,4,9,16,25} de todos os números x2 tal que x éum elemento do conjunto {1,2,3,4,5}.
94/104
List comprehension (cont.)
I Em Haskell também há uma notação de compreensão similarque pode ser usada para construir novas listas a partir de listasconhecidas.
I Exemplo:[ x^2 | x <- [1..5] ]
é a lista [1,4,9,16,25] de tdos os números x^2 tal que x é umelmento da lista [1,2,3,4,5].
95/104
List comprehension (cont.)
I A expressão x <- [1..5] é chamada gerador, já que elainforma como gerar valores para a variável x.
I Compreensões podem ter múltiplos geradores, separados porvírgula.
I Exemplo:[(x,y) | x <- [1,2,3], y <- [4,5]] [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
96/104
List comprehension (cont.)
I Se a ordem dos geradores for trocada, a ordem dos elementosna lista resultante também é trocada.
I Exemplo:[(x,y) | y <- [4,5], x <- [1,2,3]] [(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)]
97/104
List comprehension (cont.)
I Geradores múltiplos são semelhantes a loops aninhados: osúltimos geradores são como loops mais profundamenteaninhados cujas variáveis mudam mais freqüentemente.
I Exemplo:[(x,y) | y <- [4,5], x <- [1,2,3]] [(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)]
Como x <- [1,2,3] é o último gerador, o valor do componentex de cada par muda mais frequentemente.
98/104
List comprehension (cont.)
I Geradores posteriores podem depender de variáveisintroduzidas em geradores anteriores.
I Exemplo:[(x,y) | x <- [1..3], y <- [x..3]] [(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)]
a lista [(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)] de todos ospares de números (x,y) tal que x e y são elementos da lista[1..3] e y >= x.
99/104
List comprehension (cont.)
I Exemplo:Usando geradores dependentes pode-se definir a função queconcatena uma lista de listas:concat :: [[a]] -> [a]concat xss = [x | xs <- xss, x <- xs]
concat [[1,2,3],[4,5],[6]] [1,2,3,4,5,6]
100/104
List comprehension (cont.)
I List comprehensions podem usar guardas para restringir osvalores produzidos por geradores anteriores.
I Exemplo:[x | x <- [1..10], even x] [2,4,6,8,10]
a lista de todos os números x tal que x é um elemento da lista[1..10] e x é par.
101/104
List comprehension (cont.)
I Exemplo:Usando uma guarda podemos definir uma função que mapeiaum número inteiro positivo à sua lista de fatores:factors :: Int -> [Int]factors n = [x | x <- [1..n], n ‘mod‘ x == 0]
Exemplos de aplicação da função:factors 15 [1,3,5,15]factors 120 [1,2,3,4,5,6,8,10,12,15,20,24,30,40,60,120]
102/104
List comprehension (cont.)
I Exemplo:Um número inteiro positivo é primo se seus únicos fatores são 1e ele próprio. Assim, usando fatores que podemos definir umafunção que decide se um número é primo:prime :: Int -> Boolprime n = factors n == [1,n]
Exemplos de aplicação da função:prime 15 Falseprime 7 True
103/104
List comprehension (cont.)
I Exemplo:Usando um guarda agora podemos definir uma função queretorna a lista de todos os números primos até um determinadolimite:primes :: Int -> [Int]primes n = [x | x <- [2..n], prime x]
Exemplos de aplicação da função:primes 40 [2,3,5,7,11,13,17,19,23,29,31,37]primes 12 [2,3,5,7,11]
Recommended