linguagem funcional haskell - udesc - cct de programação paradigmas de programaÇÃo prof....
TRANSCRIPT
Paradigmas de Programação
PARADIGMAS DE PROGRAMAÇÃO
Prof. Claudinei Dias
email: [email protected]
Linguagem Funcional Haskell
Bacharelado em Ciência da Computação
Paradigmas de Programação
Principais Linguagens Funcionais
• LISP (John McCarthy, 1960)
• ML (Robin Milner, 1979)
• Miranda (David Turner, 1986)
• Haskell (S. Peyton Jones & P. Wadler, 1992)
2
Paradigmas de Programação
Introdução
• Programação Haskell: – A Linguagem Haskell é baseada na avaliação de expressões.
– Haskell avalia (simplifica) a expressão passada até sua forma normal.
– Principais conceitos: • Casamento de padrões
• Função de ordem superior
• Avaliação Lazy
– Exemplos:
Haskell> ((9*6)+(59/3)) *27
quadrado :: Int -> Int
quadrado x = x * x
Haskell> quadrado 2
4
3
Paradigmas de Programação
• Não possuir tipos explícitos
• Explicitar o tipo de uma função:
f: :T1 ->T2
- indica que o argumento de f tem tipo T1 e o resultado tem tipo T2
f:: (T1 x ... x Tn) -> T
- f possui n argumentos de tipos T1, ..., Tn, respectivamente, e resultado do tipo T
- Observe as declarações:
f:: ((T1 -> T2) x T3) -> T4
- f tem 2 argumentos: uma função (T1 -> T2) e um outro do tipo T3;
O resultado de f é do tipo T4
f: :T1 -> (T2 -> T3)
- f tem 1 argumento (T1) e produz como resultado uma função (T2 -> T3)
Tipos
Paradigmas de Programação
• Listas de vários tipos:
[1, 2, 3, 4] :: [Int]
[‘H’, ‘a’, ’s’, ‘k’, ‘e’, ‘l’, ‘l’] :: [Char]
[False, True, True] :: [Bool]
[[1,2,3], [2,3], [3,4,5,6]] :: [[Int]]
[(1,’a’), (2, ‘b’) , (3, ‘c’)] :: [(Int, Char)]
[(/), (**), logBase] :: [Float -> Float -> Float]
[] :: [Bool]
[] :: [Float]
[] :: [Int -> Int]
Listas
Paradigmas de Programação
• Listas de vários tipos:
Haskell > [1 .. 6]
[1, 2, 3, 4, 5, 6]
Haskell > [2,4 .. 10]
[2, 4, 6, 8, 10]
Haskell > [1,3 .. 10]
[1, 3, 5, 7, 9]
• O operador (:) é o operador de construção de listas
[1] = 1 : []
[1, 2, 3, 4] = 1 : 2 : 3 : 4 : []
Listas
Paradigmas de Programação
• Por não ter tipos explícitos, funções podem apresentar comportamento polimórfico
• Listas de vários tipos:
(:) :: t -> [t] -> [t]
(:) :: Int -> [Int] -> [Int]
(:) :: Char -> [Char] -> [Char]
(:) :: Bool -> [Bool] -> [Bool]
(...)
(:) :: t -> [t] -> [t]
• Por exemplo, a declaração
– Let fun Id x = x in ...
Permite que Id seja aplicada a qualquer argumento (de qualquer tipo)
Polimorfismo
Paradigmas de Programação
Funções
• mini :: Int -> Int -> Int
-- função que mostra o menor valor entre dois inteiros
mini a b
| a <= b = a
| otherwise = b
• Decidir qual é o menor são usados guards (guardas) que são expressões booleanas iniciadas por uma barra |
Haskell > mini 2 3
2
• Qualquer operador pode ser usado como função, e qualquer função pode ser usada como um operador, basta incluir o operador entre parênteses (), e a função entre crases ``
Haskell> (+) 2 3 Haskell> 10 `mod` 3
5 1
Paradigmas de Programação
• Pattern matching
– uma função é definida por várias equações
– cada uma delas possuindo um padrão no seu lado esquerdo
• Exemplo:
fib :: Int -> Int
fib 0 = 0 -- equação que aplica-se ao caso 0
fib 1 = 1 -- equação que aplica-se ao caso 1
fib n = fib (n-2) + fib (n-1) -- aplica-se a n > 1
• Vantagens:
– Concisão e clareza
– Mais próxima a uma definição matemática
Funções - Casamento de Padrões
Paradigmas de Programação
Funções recursivas
fatorial :: Int -> Int
fatorial 0 = 1
fatorial n = n * fatorial (n-1)
Exemplo de avaliação:
fatorial 3
= 3 * (fatorial 2)
= 3 * 2 * (fatorial 1)
= 3 * 2 * 1 * (fatorial 0)
= 3 * 2 * 1 * 1 (1)
= 6 Multiplicação
Paradigmas de Programação
Funções de Ordem Superior
• High order functions
– Funções de Primeira Ordem: • Parâmetros e resultados não são funções
– Funções de Ordem Superior: • São funções que recebem outras funções como argumento
– O contexto inclui um único componente:
• mapeamento de identificadores em valores
– O resultado da avaliação de uma expressão pode ser uma função
– Uma função pode ser argumento de outra função
Paradigmas de Programação
• High order functions
– Funções Curried
– Mapas e filtros
– Lambdas
Funções de Ordem Superior
Paradigmas de Programação
Permite currificação (Currying)
• Considere as seguintes definições: soma :: Int -> Int -> Int
soma x y = x + y
Haskell > soma 2 8
10
incrementa :: Int -> Int
incrementa = soma 1
Haskell > incremeta 4
5
• Observe que soma é sempre aplicada a dois argumentos e retorna soma deles, enquanto incremento pode ser aplicada só a um argumento, retornando uma função que espera o outro argumento.
Paradigmas de Programação
Funções sobre listas
Uma lista com head a e tail x é escrita (a:x)
somaLista [] = 0
somaLista (a:x) = a + somaLista x
Haskell> somaLista [1, 2, 3 ,4 ,5]
15
somaLista [1, 2, 3, 4, 5]
= 1 + somaLista [2, 3, 4, 5]
= 1 + ( 2 + somaLista [3, 4, 5])
= 1 + (2 + ( 3 + somaLista [4, 5]))
= 1 + (2 + ( 3 + ( 4 + somaLista [5])))
= 1 + (2 + ( 3 + ( 4 + ( 5 + somaLista []))))
= 1 + (2 + ( 3 + ( 4 + ( 5 + 0))))
= 15
head e tail head(x : xs) = x tail(x : xs) = xs
Concatenação [] ^^ ys = ys (x : xs) ^^ ys = x : (xs ^^ ys)
Paradigmas de Programação
Compreensão de listas
Uma lista descrita na notação de conjunto
[ 2 * a | a < - list ]
a lista list é [1, 7, 3]
a <-list é chamado de generator (gerador) geradores
even a podem ser combinados com predicates (predicados )
Haskell > [2* a | a<- [1, 7, 3]]
[2, 14, 6]
Haskell > [ a | a<-list, even a]
[]
Paradigmas de Programação
Compreensão de listas
• três casos:
– folding, que é a colocação de um operador entre os elementos de uma lista
– filtering, que significa filtrar alguns elementos
– mapping, que é a aplicação de funções a todos os elementos da lista.
Paradigmas de Programação
Compreensão de listas
Foldr1
• Esta função coloca um operador entre os elementos de uma lista
foldr1 (+) [ x1, x2, ..., xn] = x1 + x2 + ... + xn
Listas foldr1 :: (t -> t -> t) -> [t] -> t foldr1 f [a] = a foldr1 f (a:b:x) = f a (foldr1 f (b:x))
Haskell > foldr1 (+) [1,2,3] 6
Paradigmas de Programação
Compreensão de listas
Filter
• A função filter filtra a lista através de um predicado ou propriedade (função que tem tipo t -> Bool)
par :: Int -> Bool
par n = (n `mod` 2 == 0)
Listas filter :: (t ->Bool) -> [t] -> [t] filter p [] = [] filter p (a:x) | p a = a: filter p x | otherwise = filter p x
Compreensão de Listas
filter p x = [ a | a <- x, p a]
Haskell > filter par [2, 4, 5, 6, 10, 11] [2, 4, 6, 10]
Paradigmas de Programação
Compreensão de listas
Map
• Para se aplicar f em uma lista (a:x), o head será f aplicado em a, e o tail será dado por mapear f na lista x
Listas map :: (t -> u) -> [t] -> [u] map f [] = [] map f (a:x) = f a : map f x
Compreensão de Listas
map f list = [f a | a < -list]
Haskell > map length [“Haskell”, “Hugs”, ”GHC”] [7, 4, 3] Haskell > map (2*) [1, 2, 3] [2, 4, 6]
Currying incrementaLista :: [Int] -> Int incrementaLista = map (soma 1) Haskell > incrementaL [1,2,3,4]
Paradigmas de Programação
• Ao invés de usar equações para definir funções,
• Utiliza-se uma notação lambda:
– a função não precisa ter um nome.
sucessor :: Int -> Int
sucessor x = x+1
• poderia ser definida na notação lambda assim:
λx. x+1
ou
\x -> x + 1
Haskell > (\x -> x + 1) 10
11
Cálculo Lambda
Paradigmas de Programação
Compreensão de Listas • bubble sort bubblesort [] = []
bubblesort l = bubbleOrd l (length2 l)
bubbleOrd l 0 = l
bubbleOrd l n = bubbleOrd (swap l) (n-1)
swap [x] = [x]
swap(x:y:zs)
| x > y = y : swap (x:zs)
| otherwise = x : swap (y:zs)
length2 [] = 0
length2 (x:xs) = 1 + (length2 xs)
Exemplos
Paradigmas de Programação
Compreensão de Listas • quicksort usando compreensão de listas
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
let smallerSorted = quicksort [a | a <- xs, a <= x]
biggerSorted = quicksort [a | a <- xs, a > x]
in smallerSorted ++ [x] ++ biggerSorted
Exemplos
Paradigmas de Programação
Compreensão de Listas • quicksort usando filter
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
let smallerSorted = quicksort (filter (<=x) xs)
biggerSorted = quicksort (filter (>x) xs)
in smallerSorted ++ [x] ++ biggerSorted
Exemplos
Paradigmas de Programação
Bibliografia da Disciplina
24
BIBLIOGRAFIA :
MITCHELL, John C. Concepts in Programming Languages, Cambridge University Press, 2003. SEBESTA, Robert W. Conceitos de linguagens de programação. 9.ed. São Paulo: Bookman, 2011. 792 p. GABBRIELLI, Maurizio and MARTINI, Simone. Undergraduate topics in computer science, “Programming Languages: Principles and Paradigms” 2010. SÁ, Claudio Cesar de; SILVA, Márcio Ferreira da. Haskell: uma abordagem prática. São Paulo: Novatec, 2006. 287 p. IERUSALIMSCHY, Roberto. Programming in Lua. 2ª edição, 2006. !http://haskell.tailorfontela.com.br/chapters