Programação Funcional
em Haskell
3a Reunião — Listas
Conteúdo e objetivos
 Introdução à programação funcional usando Haskell
 Objetivos de aprendizagem
 Fundamentos sobre listas;
 Noções sobre listas;
 Construção de lista por compreensão;
 Funções sobre listas;
Fundamentos
Uma lista é uma estrutura de dados que representa uma
coleção de objetos homogêneos em sequência.
Para alcançar qualquer elemento, todos os anteriores a
ele devem ser recuperados.
Em programação, uma lista vazia (representada por [ ] em
Haskell) é a estrutura-base da existência de uma lista..
Listas em Haskell
Uma lista é composta sempre de dois segmentos: cabeça
(head) e corpo (tail). A cabeça da lista é sempre o primeiro
elemento.
[ 'a', 'b', 'c', 'd' ] 'a': [ 'b', 'c', 'd' ]
‘a’ 1° elemento ['b', 'c', 'd' ] corpo da lista
> ['a','b','c','d']
"abcd"
> 'a':['b','c','d']
"abcd“
Operador (:)
O símbolo (:) é o operador de construção de listas. Toda lista é
construída através deste operador. Podemos verificar que este
operador é polimórfico, usando o comando type:
> :type (:)
(:) :: a -> [a] -> [a]
O operador deve ser aplicado á argumentos de um
mesmo tipo.
Prelude> 'a':['b','c','d']
"abcd"
Prelude> 2:[4,6,8]
[2,4,6,8]
Listas em Haskell
Prelude> 'a':['b','c','d']
"abcd"
Prelude>1:[2,3]
[1,2,3]
Prelude>['a','c','f'] == 'a':['c','f']
True
Prelude>[1,2,3] == 1:2:3:[]
True
Prelude>1:[2,3] == 1:2:[3]
True
Prelude> “Quixada" == ‘Q':[‘u',‘i',‘x',‘a‘ ,’d’, ‘a’]
True
Prelude> “Ruth" == ‘R':[‘u',‘t',‘h']
True
Listas e Tipos
Uma lista é uma coleção de elementos de um dado tipo. Para
todo tipo t existe uma lista [t] para seus elementos. [1,2,3]
Prelude> [1,2,3]::[Int]
[1,2,3]
Prelude> [True,True,False]::[Bool]
[True,True,False]
Prelude> [(1,2),(4,5),(0,8)]::[(Int,Int)]
[(1,2),(4,5),(0,8)]
Prelude> [[2,3,4],[5],[],[3,3]]::[[Int]]
[[2,3,4],[5],[],[3,3]]
Escrevendo Listas
Pode-se definir uma lista indicando os limites inferior e superior
de um conjunto conhecido, onde existe uma relação de ordem
entre os elementos, no seguinte formato:
[ <limite-inferior> .. <limite-superior> ]
> [1..4]
[1,2,3,4]
> ['m'..'n']
"mn"
> [1,3..6]
[1,3,5]
> ['a','d'..'p']
"adgjmp"
Escrevendo Listas
Podemos definir qualquer progressão aritmética em uma lista
utilizando a seguinte notação:
[ <1o. termo>, <2o. termo> .. <limite-superior> ]
> [7,6..3] > [6,5..0]
[7,6,5,4,3] [6,5,4,3,2,1,0]
> [-5,2..16] > [5,6..5]
[-5,2,9,16] [5]
> [1,1.1 .. 2]
[1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0]
Listas por Compreensão
Definição
A definição de listas por compreensão é feita por um construtor de
listas que utiliza conceitos e notações da teoria dos conjuntos.
Assim, para um conjunto A temos:
A = { E(x) | x C P1(x) ^ ... ^ Pn(x) }
sendo E(x) uma expressão em x, C um conjunto inicial para os
valores de x e os vários Pi (x) são proposições em x.
O conjunto A é escrito em Haskell da seguinte forma:
A = [ E(x) | x <- lista, P1(x), ... , Pn(x) ]
Listas por Compreensão
O conjunto dos quadrados dos números inteiros é definido pela
expressão:
A = { x | x }
Em Haskell, podemos escrever A para listas finitas ou infinitas
da seguinte forma:
listaQuad = [ x^2 | x <- [1..30] ]
listaQuadInf = [ x^2 | x <- [1..] ]
Listas por Compreensão
Prelude> [2*x | x <- [1..10]]
[2,4,6,8,10,12,14,16,18,20]
Prelude> [2*x | x <- [1..10] , 2*x >= 12]
[12,14,16,18,20]
Prelude> [x+y | x <- [1..10] , y <- [11..20]]
[12,13,14,15,16,17,18,19,20,21,13,14,15,16,17,18,19,20,21,22,14,15,16,17,1
8,19,20,21,22,23,15,16,17,18,19,20,21,22,23,24,16,17,119,20,21,22,23,24,2
5,17,18,19,20,21,22,23,24,25,26,18,19,20,21,22,23,24,25,26,27,19,20,21,22,
23,24,25,26,27,28,20,21,22,23,24,526,27,28,29,21,22,23,24,25,26,27,28,29,
30]
Prelude>
Listas por Compreensão
--Defina uma função divisores de n que retorna uma
--lista dos divisores de n.
Prelude> let divisores n = [ x| x <- [1..n] , mod n x == 0 ]
Prelude> divisores 12
[1,2,3,4,6,12]
Listas por Compreensão
--Defina uma função mdc a b que calcula o máximo
--divisor comum múltiplo comum de a e b.
Prelude> let comum a b = [ x | x <- [1..a] , mod a x ==0 , mod b x ==0 ]
Prelude> comum 12 24
[1,2,3,4,6,12]
Prelude> let mdc a b = maximum ( comum a b )
Prelude> mdc 12 24
12
Prelude> mdc 12 15
3
Listas por Compreensão
--Calcule a soma de todos os números múltiplos de 3
--ou 5 menores que 1000.
Prelude> sum [ x | x <- [1..1000] , mod x 3 ==0 || mod x 5 ==0 ]
234168
--Crie uma função que imprima apenas
--os caracteres maiúsculos de uma string.
Prelude> let imprimaMaiusculas st = [c | c <- st , elem c ['A'..'Z'] ]
Prelude> imprimaMaiusculas
“PhonoRrjOetGvirtusRamicusAMlaeticiaAÇÃO FUNCIONAL USANDO
HASKELL“
“PROGRAMAÇÃOFUNCIONALUSANDOHASKELL“
Prelude> imprimaMaiusculas “HaprendAerSeKhEumaLLvirCtuAdePIT
VsaIbTerAeEhApoMIdeCUrS “
“HASKELLCAPITVITAEAMICUS“
Funções sobre listas
função descrição exemplo
(++) Concatena duas
ou mais listas
> [1,2,3]++[4,5,6]
[1,2,3,4,5,6]
concat Recebe uma lista
de listas e as
concatena
> concat [[1,2],[3,4]]
[1,2,3,4]
Elem Verifica se um
elemento
pertence a lista
>elem 5 [1,5,10]
True
null Retorna
verdadeiro (True)
se uma lista é
vazia
>null []
True
length Tamanho de uma
lista
>length “wesley“
6
Funções sobre listas
função descrição exemplo
head Retorna o
1°elemento
> head “thiago"
‘t'
tail Retorna o corpo
da lista
> tail “Ricardo"
“icardo"
last Retorna o último
elemento da lista
> last [4,3,2]
2
(!!) Operador de
índice da lista,
retorna o
elemento mantido
numa posição
>[1,3,5,7,9] !!0
1
> (!!)[‘c',‘a',‘i‘,’k’,’e’] 2
‘i'
reverse Reverso da lista > reverse [4,5,2,2]
[2,2,5,4]
Funções sobre listas
função descrição Exemplo
replicate Constrói uma lista
pela replicação de
um elemento
> replicate 4 'c
“cccc”
product Retorna o produto
dos elementos da
lista
> product [5,3,6,1]
90
sum Retorna a soma
dos elementos
> sum [4,5,7,2,1]
19
maximum Retorna o maior
elemento
> Maximum [4,5,2,-20,4,2]
5
minimum Retorna o menor
elemento
> minimum [5.2,0.3,7.2]
0.3
Funções sobre listas
função descrição Exemplo
take Gera uma lista
com os n 1°s
elementos da lista
original
> take 4 [‘c',‘r',‘i',‘s‘, ‘l‘,‘a‘,‘n‘, ‘i‘, ‘o‘]
“cris”
drop Retira n
elementos do
início da lista
> drop 3 [3,3,4,4,5,5]
[4,5,5]
takeWhile Retorna o maior
segmento inicial
de uma lista que
satisfaz uma
condição
>takeWhile (<10) [1,3,13,4]
[1,3]
dropWhile Retira o maior
segmento inicial
de uma lista que
satisfaz uma
condição
>dropWhile (<10) [1,3,13,4]
[13,4]
Funções sobre listas
função Descrição Exemplo
splitAt Divide uma lista
num par de sub-
listas fazendo a
divisão numa
determinada
posição
>splitAt 2 [3,4,2,1,5]
([3,4],[2,1,5])
zip Recebe duas
listas como
entrada e retorna
> zip [1,2] ['a','b']
uma lista de
pares
>zip [1,2] ['a','b']
[(1,'a'),(2,'b')]
Bibliografia
Haskell - Uma abordagem prática. Cláudio César de Sá e
Márcio Ferreira da Silva. Novatec, 2006.
Agradecimentos
Ao Prof°- Ricardo Reis e a todos os participantes do projeto
haskell ufc.

Haskell aula3 listas

  • 1.
  • 2.
    Conteúdo e objetivos Introdução à programação funcional usando Haskell  Objetivos de aprendizagem  Fundamentos sobre listas;  Noções sobre listas;  Construção de lista por compreensão;  Funções sobre listas;
  • 3.
    Fundamentos Uma lista éuma estrutura de dados que representa uma coleção de objetos homogêneos em sequência. Para alcançar qualquer elemento, todos os anteriores a ele devem ser recuperados. Em programação, uma lista vazia (representada por [ ] em Haskell) é a estrutura-base da existência de uma lista..
  • 4.
    Listas em Haskell Umalista é composta sempre de dois segmentos: cabeça (head) e corpo (tail). A cabeça da lista é sempre o primeiro elemento. [ 'a', 'b', 'c', 'd' ] 'a': [ 'b', 'c', 'd' ] ‘a’ 1° elemento ['b', 'c', 'd' ] corpo da lista > ['a','b','c','d'] "abcd" > 'a':['b','c','d'] "abcd“
  • 5.
    Operador (:) O símbolo(:) é o operador de construção de listas. Toda lista é construída através deste operador. Podemos verificar que este operador é polimórfico, usando o comando type: > :type (:) (:) :: a -> [a] -> [a] O operador deve ser aplicado á argumentos de um mesmo tipo. Prelude> 'a':['b','c','d'] "abcd" Prelude> 2:[4,6,8] [2,4,6,8]
  • 6.
    Listas em Haskell Prelude>'a':['b','c','d'] "abcd" Prelude>1:[2,3] [1,2,3] Prelude>['a','c','f'] == 'a':['c','f'] True Prelude>[1,2,3] == 1:2:3:[] True Prelude>1:[2,3] == 1:2:[3] True Prelude> “Quixada" == ‘Q':[‘u',‘i',‘x',‘a‘ ,’d’, ‘a’] True Prelude> “Ruth" == ‘R':[‘u',‘t',‘h'] True
  • 7.
    Listas e Tipos Umalista é uma coleção de elementos de um dado tipo. Para todo tipo t existe uma lista [t] para seus elementos. [1,2,3] Prelude> [1,2,3]::[Int] [1,2,3] Prelude> [True,True,False]::[Bool] [True,True,False] Prelude> [(1,2),(4,5),(0,8)]::[(Int,Int)] [(1,2),(4,5),(0,8)] Prelude> [[2,3,4],[5],[],[3,3]]::[[Int]] [[2,3,4],[5],[],[3,3]]
  • 8.
    Escrevendo Listas Pode-se definiruma lista indicando os limites inferior e superior de um conjunto conhecido, onde existe uma relação de ordem entre os elementos, no seguinte formato: [ <limite-inferior> .. <limite-superior> ] > [1..4] [1,2,3,4] > ['m'..'n'] "mn" > [1,3..6] [1,3,5] > ['a','d'..'p'] "adgjmp"
  • 9.
    Escrevendo Listas Podemos definirqualquer progressão aritmética em uma lista utilizando a seguinte notação: [ <1o. termo>, <2o. termo> .. <limite-superior> ] > [7,6..3] > [6,5..0] [7,6,5,4,3] [6,5,4,3,2,1,0] > [-5,2..16] > [5,6..5] [-5,2,9,16] [5] > [1,1.1 .. 2] [1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0]
  • 10.
    Listas por Compreensão Definição Adefinição de listas por compreensão é feita por um construtor de listas que utiliza conceitos e notações da teoria dos conjuntos. Assim, para um conjunto A temos: A = { E(x) | x C P1(x) ^ ... ^ Pn(x) } sendo E(x) uma expressão em x, C um conjunto inicial para os valores de x e os vários Pi (x) são proposições em x. O conjunto A é escrito em Haskell da seguinte forma: A = [ E(x) | x <- lista, P1(x), ... , Pn(x) ]
  • 11.
    Listas por Compreensão Oconjunto dos quadrados dos números inteiros é definido pela expressão: A = { x | x } Em Haskell, podemos escrever A para listas finitas ou infinitas da seguinte forma: listaQuad = [ x^2 | x <- [1..30] ] listaQuadInf = [ x^2 | x <- [1..] ]
  • 12.
    Listas por Compreensão Prelude>[2*x | x <- [1..10]] [2,4,6,8,10,12,14,16,18,20] Prelude> [2*x | x <- [1..10] , 2*x >= 12] [12,14,16,18,20] Prelude> [x+y | x <- [1..10] , y <- [11..20]] [12,13,14,15,16,17,18,19,20,21,13,14,15,16,17,18,19,20,21,22,14,15,16,17,1 8,19,20,21,22,23,15,16,17,18,19,20,21,22,23,24,16,17,119,20,21,22,23,24,2 5,17,18,19,20,21,22,23,24,25,26,18,19,20,21,22,23,24,25,26,27,19,20,21,22, 23,24,25,26,27,28,20,21,22,23,24,526,27,28,29,21,22,23,24,25,26,27,28,29, 30] Prelude>
  • 13.
    Listas por Compreensão --Definauma função divisores de n que retorna uma --lista dos divisores de n. Prelude> let divisores n = [ x| x <- [1..n] , mod n x == 0 ] Prelude> divisores 12 [1,2,3,4,6,12]
  • 14.
    Listas por Compreensão --Definauma função mdc a b que calcula o máximo --divisor comum múltiplo comum de a e b. Prelude> let comum a b = [ x | x <- [1..a] , mod a x ==0 , mod b x ==0 ] Prelude> comum 12 24 [1,2,3,4,6,12] Prelude> let mdc a b = maximum ( comum a b ) Prelude> mdc 12 24 12 Prelude> mdc 12 15 3
  • 15.
    Listas por Compreensão --Calculea soma de todos os números múltiplos de 3 --ou 5 menores que 1000. Prelude> sum [ x | x <- [1..1000] , mod x 3 ==0 || mod x 5 ==0 ] 234168 --Crie uma função que imprima apenas --os caracteres maiúsculos de uma string. Prelude> let imprimaMaiusculas st = [c | c <- st , elem c ['A'..'Z'] ] Prelude> imprimaMaiusculas “PhonoRrjOetGvirtusRamicusAMlaeticiaAÇÃO FUNCIONAL USANDO HASKELL“ “PROGRAMAÇÃOFUNCIONALUSANDOHASKELL“ Prelude> imprimaMaiusculas “HaprendAerSeKhEumaLLvirCtuAdePIT VsaIbTerAeEhApoMIdeCUrS “ “HASKELLCAPITVITAEAMICUS“
  • 16.
    Funções sobre listas funçãodescrição exemplo (++) Concatena duas ou mais listas > [1,2,3]++[4,5,6] [1,2,3,4,5,6] concat Recebe uma lista de listas e as concatena > concat [[1,2],[3,4]] [1,2,3,4] Elem Verifica se um elemento pertence a lista >elem 5 [1,5,10] True null Retorna verdadeiro (True) se uma lista é vazia >null [] True length Tamanho de uma lista >length “wesley“ 6
  • 17.
    Funções sobre listas funçãodescrição exemplo head Retorna o 1°elemento > head “thiago" ‘t' tail Retorna o corpo da lista > tail “Ricardo" “icardo" last Retorna o último elemento da lista > last [4,3,2] 2 (!!) Operador de índice da lista, retorna o elemento mantido numa posição >[1,3,5,7,9] !!0 1 > (!!)[‘c',‘a',‘i‘,’k’,’e’] 2 ‘i' reverse Reverso da lista > reverse [4,5,2,2] [2,2,5,4]
  • 18.
    Funções sobre listas funçãodescrição Exemplo replicate Constrói uma lista pela replicação de um elemento > replicate 4 'c “cccc” product Retorna o produto dos elementos da lista > product [5,3,6,1] 90 sum Retorna a soma dos elementos > sum [4,5,7,2,1] 19 maximum Retorna o maior elemento > Maximum [4,5,2,-20,4,2] 5 minimum Retorna o menor elemento > minimum [5.2,0.3,7.2] 0.3
  • 19.
    Funções sobre listas funçãodescrição Exemplo take Gera uma lista com os n 1°s elementos da lista original > take 4 [‘c',‘r',‘i',‘s‘, ‘l‘,‘a‘,‘n‘, ‘i‘, ‘o‘] “cris” drop Retira n elementos do início da lista > drop 3 [3,3,4,4,5,5] [4,5,5] takeWhile Retorna o maior segmento inicial de uma lista que satisfaz uma condição >takeWhile (<10) [1,3,13,4] [1,3] dropWhile Retira o maior segmento inicial de uma lista que satisfaz uma condição >dropWhile (<10) [1,3,13,4] [13,4]
  • 20.
    Funções sobre listas funçãoDescrição Exemplo splitAt Divide uma lista num par de sub- listas fazendo a divisão numa determinada posição >splitAt 2 [3,4,2,1,5] ([3,4],[2,1,5]) zip Recebe duas listas como entrada e retorna > zip [1,2] ['a','b'] uma lista de pares >zip [1,2] ['a','b'] [(1,'a'),(2,'b')]
  • 21.
    Bibliografia Haskell - Umaabordagem prática. Cláudio César de Sá e Márcio Ferreira da Silva. Novatec, 2006.
  • 22.
    Agradecimentos Ao Prof°- RicardoReis e a todos os participantes do projeto haskell ufc.