linguagem funcional haskell - udesc - cct de programação paradigmas de programaÇÃo prof....

24
Paradigmas de Programação PARADIGMAS DE PROGRAMAÇÃO Prof. Claudinei Dias email: [email protected] Linguagem Funcional Haskell Bacharelado em Ciência da Computação

Upload: duongkhanh

Post on 10-Nov-2018

229 views

Category:

Documents


0 download

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