Programação Funcional. Capítulo 13. Mônadas. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto 2013.



Documentos relacionados
Programação Funcional. Capítulo 13. Mônadas. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto 2012.

Programas Interativos: Valores Aleatórios

Capítulo 2: Introdução à Linguagem C

LP II Estrutura de Dados. Introdução e Linguagem C. Prof. José Honorato F. Nunes honorato.nunes@ifbaiano.bonfim.edu.br

Linguagem algorítmica: Portugol

Métodos Os métodos de uma classe podem ser classificados como construtores, destrutores, funções ou procedimentos.

INF 1005 Programação I

INTRODUÇÃO À PROGRAMAÇÃO BCC 201 TURMAS 31, 32 E AULA TEÓRICA 4 PROF. MARCELO LUIZ SILVA (R E D)

CONVENÇÃO DE CÓDIGO JAVA

Programação Funcional. Aula 10. Parsers. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto /74 ...

Interpretação e Compilação de Linguagens de Programação Sintaxe e Semântica

Programação Funcional. Capítulo 21. Parsers. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto 2018.

Programação Funcional. Aula 5. Funções Recursivas. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto 2011.

CAPÍTULO 3 - TIPOS DE DADOS E IDENTIFICADORES

Componentes da linguagem C++

Programação Funcional. Aula 4. Definindo Funções. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto 2011.

O Processo de Programação

Linguagem e Técnicas de Programação I Operadores, expressões e funções. Prof. MSc. Hugo Souza Material desenvolvido por: Profa.

Programação: Estruturas de seleção

Aula 4 Pseudocódigo Tipos de Dados, Expressões e Variáveis

AMBIENTE PARA AUXILIAR O DESENVOLVIMENTO DE PROGRAMAS MONOLÍTICOS

Algoritmos e Estruturas de Dados I 01/2013. Estruturas Condicionais e de Repetição (parte 2) Pedro O.S. Vaz de Melo

Introdução aos cálculos de datas

Resolução de problemas e desenvolvimento de algoritmos

Algoritmos com VisuAlg

Curso: Ciência da Computação Disciplina: Construção de Compiladores Período: Prof. Dr. Raimundo Moura

A lógica de programação ajuda a facilitar o desenvolvimento dos futuros programas que você desenvolverá.

ESTRUTURA CONDICIONAL

Orientação a Objetos

Simulação de Caixa Automático

VisuALG Estruturas de Repetição. Professores: Vilson Heck Junior Felipe Schneider Costa

Orientação a Objetos

Algoritmos e Programação de Computadores

Introdução à Engenharia de

Conceitos básicos da linguagem C

BARRAMENTO DO SISTEMA

Geração de código. Ivan Ricarte INTRODUÇÃO À COMPILAÇÃO

Apresentar os conceitos básicos e as estruturas de linguagem relacionadas à tomada de decisão ofertadas pela linguagem C, tais como:

Tipos Algébricos. Programação Funcional. Capítulo 11. José Romildo Malaquias Departamento de Computação Universidade Federal de Ouro Preto

Programação Funcional 9 a Aula Programas interativos

Introdução à Programação

Processamento da Informação Teoria. Algoritmos e Tipos de dados

ALGORITMOS PARTE 01. Fabricio de Sousa Pinto

Java Como Programar, 8/E

Curso de Programação Computadores

O modelo do computador

PROGRAMAÇÃO ESTRUTURADA. CC 2º Período

Aula de Informática (disponível em Sumário

1.2 Uma linguagem de programação muito simples

Programação Funcional. Capítulo 1. Introdução. José Romildo Malaquias. Departamento de Computação Universidade Federal de Ouro Preto 2015.

2. OPERADORES ALGORITMOS, FLUXOGRAMAS E PROGRAMAS FUNÇÕES... 10

Programas Interativos

Novas Tecnologias no Ensino da Matemática

Linguagem C: Estruturas de Controle. Prof. Leonardo Barreto Campos 1

Curso: Técnico de Informática Disciplina: Redes de Computadores. 1- Apresentação Binária

ULA Sinais de Controle enviados pela UC

Tutorial do Iniciante. Excel Básico 2010

Faculdade de Computação Programação Funcional (BCC/BSI) 1 Período Aula Prática: Classes e Tipos Algébricos

PLANILHA PARA GERENCIAR NOTAS DAS TURMAS

Material Teórico - Módulo de Divisibilidade. MDC e MMC - Parte 1. Sexto Ano. Prof. Angelo Papa Neto

Algoritmos e Programação Estruturada

Introdução. INF1005 Programação I 33K Prof. Gustavo Moreira gmoreira@inf.puc-rio.br

Universidade Federal de Itajubá Instituto de Engenharia de Sistemas e Tecnologias da Informação-IESTI PCO203 Tópicos Especiais em Programação

Capítulo 11. Conceitos de Orientação a Objetos. Rui Rossi dos Santos Programação de Computadores em Java Editora NovaTerra

Algoritmo. Linguagem natural: o Ambígua o Imprecisa o Incompleta. Pseudocódigo: o Portugol (livro texto) o Visualg (linguagem) Fluxograma

Aula 1 Tipo Abstrato de Dados

Lógica de Programação

Expressões Lógicas Comandos de Seleção

2. Representação Numérica

Algoritmos e Programação (Prática) Profa. Andreza Leite andreza.leite@univasf.edu.br

Table of Contents. PowerPoint XP

Informática no Ensino da Matemática

Instruções para a atividade

Sistemas de Numeração. Introdução ao Computador 2010/1 Renan Manola

Informática I. Aula 6. Aula 6-12/09/2007 1

&XUVRGH,QWURGXomRDR (GLWRUGH3ODQLOKDV([FHO

Programação: Tipos, Variáveis e Expressões

Geração de código intermediário. Novembro 2006

8VDQGR5HSRUW0DQDJHUFRP&ODULRQH3RVWJUH64/ -XOLR&HVDU3HGURVR 8VDQGRSDUkPHWURV

Roteiro 1: Dados, variáveis, operadores e precedência

Sistemas Operacionais e Introdução à Programação. Vetores e matrizes

1.6. Tratamento de Exceções

1. FUNÇÕES NO EXCEL 2007

CIÊNCIA DA COMPUTAÇÃO I Excel. Núm1, núm2,... são argumentos de 1 a 255 cuja soma ou valor total você deseja obter.

Curso Adonai QUESTÕES Disciplina Linguagem JAVA

Python Funções. Introdução à Programação SI1

Laboratório de Programação I

Programação de Computadores III

20 Caracteres - Tipo char

Tutorial de Matlab Francesco Franco

Programação Funcional Aulas 9, 10 & 11

Algoritmos e Programação Conceitos e Estruturas básicas (Variáveis, constantes, tipos de dados)

Algoritmo e Programação

Recursão em Listas. Universidade Federal de Uberlândia - UFU Faculdade de Computação - FACOM Lista de exercícios de Programação Funcional

13 Números Reais - Tipo float

Programas Interativos

Criar a classe Aula.java com o seguinte código: Compilar e Executar

PROGRAMAÇÃO ORIENTADA A OBJETOS -TRATAMENTO DE EXCEÇÕES. Prof. Angelo Augusto Frozza, M.Sc. frozza@ifc-camboriu.edu.br

Transcrição:

Programação Funcional Capítulo 13 Mônadas José Romildo Malaquias Departamento de Computação Universidade Federal de Ouro Preto 2013.1 1/42

1 Mônadas 2 Entrada e saída 3 Expressão do 4 Computações que podem falhar 5 Expressões aritméticas 6 Computações que produzem log 2/42

Tópicos 1 Mônadas 2 Entrada e saída 3 Expressão do 4 Computações que podem falhar 5 Expressões aritméticas 6 Computações que produzem log 3/42

Mônadas Mônadas em Haskell podem ser entendidas como descrições de computações que podem ser combinadas sequencialmente. Uma mônada pode ser executada a fim de realizar a computação por ela representada e produzir um valor como resultado. Cada mônada representa um tipo diferente de computação. 4/42

Operações monádicas básicas return return x é uma computação que, quando executada, apenas produz o resultado x. (>>=) O operador binário (>>=) é usado para fazer a combinação sequencial de duas computações. (>>=) combina duas computações de forma que, quando a computação combinada é executada, a primeira computação é executada e o seu resultado é passado para a segunda computação, que então é executada usando (ou dependendo de) o resultado da primeira. 5/42

Outras operações monádicas (>>) fail O operador binário (>>) também é usado para fazer a combinação sequencial de duas computações, porém o resultado da primeira computação é ignorado. (>>) combina duas computações de forma que, quando a computação combinada é executada, a primeira computação é executada (e seu resultado é ignorado) e em seguida a segunda computação é executada (sem depender do resultado da primeira). fail msg é uma computação que, quando executada, indica algum tipo de falha identificada pela mensagem msg. 6/42

A classe Monad Pode-se dizer que mônada é qualquer construtor de tipo de aridade 1 que suporta as operações monádicas básicas mencionadas anteriormente. Em Haskell, a classe de tipos Monad introduz as operações monádicas: class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b fail :: String -> m a p >> q = p >>= \_ -> q fail msg = error msg Nesta classe a variável restrita m representa um construtor de tipo (de aridade um), e não um tipo! Dizemos que este construtor de tipo é uma mônada. Um construtor de tipo de aridade 1 é uma mônada se existirem as operações return e (>>=) que permitem combinar valores desse tipo em sequência. 7/42

Leis das mônadas Além de implementar os métodos da classe Monad, todas as mônadas devem obedecer as seguintes leis, dadas pelas equações: return a >>= k = k a m >>= return = m m >>= (\x -> k x >>= h) = (m >>= k) >>= h 8/42

Tópicos 1 Mônadas 2 Entrada e saída 3 Expressão do 4 Computações que podem falhar 5 Expressões aritméticas 6 Computações que produzem log 9/42

Entrada e saída Uma ação de entrada e saída é representada pelo tipo IO a. IO a é um tipo abstrato em que pelo menos as seguintes operações estão disponíveis: Operações primitivas, como por exemplo: putchar :: Char -> IO () getchar :: IO Char Operações para combinar ações de entrada e saída: return :: a -> IO a return x é uma ação de E/S que quando executada não interage com o mundo e retorna x. (>>=) :: IO a -> (a -> IO b) -> IO b p >>= f é uma ação de E/S que quando executada, executa primeira a ação p e em seguida aplica a função f no resultado de p. O corpo da função f é a segunda ação da sequência. O resultado da primeira ação pode ser usado na segunda ação porque ele é passado como argumento para a função f. 10/42

Entrada e saída (cont.) As funções return e (>>=) caracterizam a classe de tipos chamada Monad. As demais funções primitivas são específicas de ações de entrada e saída. Assim IO é uma mônada e x :: IO a é uma ação monádica. 11/42

Exemplo: entrada e saída Ler um caracter e exibi-lo em maiúscula: module Main (main) where main :: IO () main = getchar >>= (\c -> putchar (toupper c)) A expressão lambda não precisa estar entre parênteses. Lembre-se de que uma expressão lambda se extende o máximo possível para a direita. module Main (main) where main :: IO () main = getchar >>= \c -> putchar (toupper c) 12/42

Tópicos 1 Mônadas 2 Entrada e saída 3 Expressão do 4 Computações que podem falhar 5 Expressões aritméticas 6 Computações que produzem log 13/42

Notação do Tipicamente computações monádicas complexas são construídas a partir de longos encadeamentos de computações mais simples combinadas usando os operadores (>>) e (>>=). Haskell oferece a expressão do, que permite combinar várias computações a serem executadas em sequência usando uma notação mais conveniente. Uma expressão do é uma extensão sintática do Haskell e sempre pode ser reescrita como uma expressão mais básica usando os operadores de sequenciamento (>>) e (>>=) e a expressão let. 14/42

Exemplo de notação do Um programa para ler dois números e exibir a sua soma: module Main (main) where main :: IO () main = do { putstrln "Digite um número:"; s1 <- getline; putstrln "Digite outro número:"; s2 <- getline; putstr "Soma: "; putstrln (show (read s1 + read s2)) } 15/42

Regra de layout com a notação do A expressão do pode usar layout em sua estrutura sintática, de maneira semelhate à expressão let e às cláusulas where. As regras de layout, por meior do uso de indentação adequada, permitem omitir as chaves { e } usadas para delimitar o corpo da expressão do e os pontos-e-vírgula ; usados para separar as ações que compõem o seu corpo. Neste caso todas as ações devem começar na mesma coluna, e se continuarem nas linhas seguintes, não podem usar colunas menores que esta coluna. 16/42

Exemplo de notação do usando layout Um programa para ler dois números e exibir a sua soma: module Main (main) where main :: IO () main = do putstrln "Digite um número:" s1 <- getline putstrln "Digite outro número:" s2 <- getline putstr "Soma: " putstrln (show (read s1 + read s2)) 17/42

Tradução da expressão do Código escrito usando a notação do é transformado automaticamente pelo compilador em expressões ordinárias que usam as funções (>>=) e (>>) da classe Monad, e a expressão let. 18/42

Tradução da expressão do (cont.) Quando houver uma única ação no corpo: do { ação } ação Exemplo: do putstrln "Bom dia, galera!" putstrln "Bom dia, galera!" Observe que neste caso não é permitido usar a forma padrão <- ação pois não há outras ações que poderiam usar variáveis instanciadas pelo casamento de padrão. 19/42

Tradução da expressão do (cont.) Quando houver duas ou mais ações sem casamento de padrão na primeira ação: do { ação ; resto } ação >> do { resto } Exemplo: do putstrln "um" ; putstrln "dois" putstrln "um" >> do putstrln "dois" putstrln "um" >> putstrln "dois" 20/42

Tradução da expressão do (cont.) Quando houver duas ou mais ações com casamento de padrão na primeira ação: do { padrão <- ação ; resto } ação >>= ( \padrão -> do { resto } ) Exemplo: do x <- getline ; putstrln ("Você digitou: " ++ x) getline >>= ( \x -> do putstrln ("Você digitou: " ++ x) ) getline >>= ( \x -> putstrln ("Você digitou: " ++ x) ) 21/42

Tradução da expressão do (cont.) Quando houver duas ou mais ações com declaração local na primeira ação: do { let declarações ; resto } let declarações in do { resto } Exemplo: do let f xs = xs ++ xs ; putstrln (f "abc") let f xs = xs ++ xs in do putstrln (f "abc") let f xs = xs ++ xs in putstrln (f "abc") 22/42

Exemplo sem usar a notação do Um programa para ler dois números e exibir a sua soma, com uso explícito dos operadores de sequenciamento: module Main (main) where main :: IO () main = putstrln "Digite um número:" >> ( getline >>= ( \s1 -> putstrln "Digite outro número:" >> ( getline >>= ( \s2 -> putstr "Soma: " >> putstrln (show (read s1 + read s2)) ) ) ) ) 23/42

Exemplo sem usar a notação do (cont.) Um programa para ler dois números e exibir a sua soma, com uso explícito dos operadores de sequenciamento. Considerando que os operadores (>>) e (>>=) são associativos à direita, e que uma expressão lambda extende-se o máximo que for possível, os parênteses usados na versão anterior não são necessários. module Main (main) where main :: IO () main = putstrln "Digite um número:" >> getline >>= \s1 -> putstrln "Digite outro número:" >> getline >>= \s2 -> putstr "Soma: " >> putstrln (show (read s1 + read s2)) 24/42

Exercícios Exercício 1 Faça um programa em Haskell que receba dois números e mostre o menor. 1. Utilize a notação do para sequenciamento das ações de E/S. 2. Utilize explicitamente os operadores (>>=) e (>>) para sequenciamento das ações de E/S. Exercício 2 Faça um programa em Haskell que receba quatro notas de um aluno, calcule e mostre a média das notas e a mensagem de aprovado ou reprovado, considerando para aprovação média 7. 1. Utilize a notação do para sequenciamento das ações de E/S. 2. Utilize explicitamente os operadores (>>=) e (>>) para sequenciamento das ações de E/S. 25/42

Tópicos 1 Mônadas 2 Entrada e saída 3 Expressão do 4 Computações que podem falhar 5 Expressões aritméticas 6 Computações que produzem log 26/42

Computações que podem falhar O construtor de tipo Maybe é uma mônada que representa computações que podem falhar. Declaração: data Maybe a = Nothing Just a instance Monad Maybe where return = Just Nothing >>= f = Nothing Just x >>= f = f x 27/42

Exemplo: agenda telefônica Uma agenda telefônica pode ser representada por uma lista de associações: agenda :: [(String,String)] agenda = [ ("Bob", "01788 665242"), ("Fred", "01624 556442"), ("Alice", "01889 985333"), ("Jane", "01732 187565") ] 28/42

Exemplo: agenda telefônica (cont.) A função lookup do prelúdio pesquisa uma chave em uma lista de associações: lookup :: Eq a => a -> [(a,b)] -> Maybe b lookup x [] = Nothing lookup x ((y,v):ys) x == y = Just v otherwise = lookup x ys 29/42

Exemplo: agenda telefônica (cont.) Queremos procurar dois itens na agenda: se algum dos itens não for encontrado, a operação falha se ambos os itens forem encontrados, resulta no par formado pelos valores correspondentes lookup2 :: Eq a => a -> a -> [(a,b)] -> Maybe (b,b) Inspecionando diretamente a estrutura de dados: lookup2 k1 k2 lst = case lookup k1 lst of Nothing -> Nothing Just v1 -> case lookup k2 lst of Nothing -> Nothing Just v2 -> Just (v1,v2) 30/42

Exemplo: agenda telefônica (cont.) Usando operações monádicas sem a notação do: lookup2 k1 k2 lst = lookup k1 lst >>= \v1 -> lookup k2 lst >>= \v2 -> return (v1,v2) Usando operações monádicas com a notação do: lookup2 k1 k2 lst = do v1 <- lookup k1 lst v2 <- lookup k2 lst return (v1,v2) 31/42

Tópicos 1 Mônadas 2 Entrada e saída 3 Expressão do 4 Computações que podem falhar 5 Expressões aritméticas 6 Computações que produzem log 32/42

Expressões aritméticas Considere o tipo Exp que representa uma expressão aritmética: data Exp = Cte Integer Som Exp Exp Sub Exp Exp Mul Exp Exp Div Exp Exp deriving (Read, Show) Uma expressão aritmética é: uma constante inteira, ou a soma de duas expressões, ou a diferença de duas expressões, ou o produto de duas expressões, ou o quociente de duas expressões. 33/42

Exemplos de expressões aritméticas -- 73/(3+3) * 8 expok = Mul (Div (Cte 73) (Som (Cte 3) (Cte 3))) (Cte 8) -- 73/(3-3) * 8 expproblema = Mul (Div (Cte 73) (Sub (Cte 3) (Cte 3))) (Cte 8) 34/42

Avaliação de expressões aritméticas Um avaliador simples de expressões aritméticas: avalia :: Exp -> Integer avalia (Cte x) = x avalia (Som a b) = avalia a + avalia b avalia (Sub a b) = avalia a - avalia b avalia (Mul a b) = avalia a * avalia b avalia (Div a b) = div (avalia a) (avalia b) 35/42

Avaliação de expressões aritméticas (cont.) Avaliando as expressões anteriores: *Main> avalia expok 96 *Main> avalia expproblema *** Exception: divide by zero A segunda expressão não pode ser avaliada, pois a divisão por zero leva a um resultado indefinido. 36/42

Exercícios Exercício 3 Redefina a função avalia para que ela não produza uma exceção quando em sua estrutura houver divisão por zero. A função deve retornar uma indicação de falha ou sucesso, juntamente com o seu valor em caso de sucesso. Use o construtor de tipo Maybe. Inspecione os resultados das avaliações das subexpressões diretamente usando análise de casos. 37/42

Exercícios (cont.) Exercício 4 Modifique a função avalia do exercício anterior para usar operações monádicas ao invés de inspecionar os resultados das avaliações das subexpressões diretamente usando análise de casos. Use explicitamente os operadores (>>=) e (>>) para sequenciamento das ações de E/S. Não use a notação do. Exercício 5 Modifique a função avalia do exercício anterior para usar a notação do para realizar as operações monádicas. Não use explicitamente os operadores (>>=) e (>>) para sequenciamento das ações de E/S. 38/42

Tópicos 1 Mônadas 2 Entrada e saída 3 Expressão do 4 Computações que podem falhar 5 Expressões aritméticas 6 Computações que produzem log 39/42

Computações que produzem log Frequentemente é desejável para uma computação produzir um fluxo de dados adicional, além dos valores computados. Logging e tracing são os exemplos mais comuns nos quais dados são gerados durante uma computação, e queremos retê-los, mas eles não são os resultados principais da computação. Definição: newtype Out a = Out (a,string) 40/42

Exemplo Redefina a função a avalia para calcular o valor de uma expressão aritmética e simultaneamente gerar um trace da avaliação de cada subexpressão. avalia :: Exp -> Out Integer 41/42

Fim 42/42