Nome TextoResumo
0 ALLEF KRISTIAN TAVARES ROCHA
1 ANDRE RICCA YOSHIDA
2 ANGELO MAEDA ROJAS
3 ANTONIO DUARTE CANTANHEDE NETO –------Monad Reader Esta monada permite lidar com dados globais, partilhados em diferentes ambientes, sem que possíveis efeitos colaterais causem problemas. data Reader e a = Reader (e -> a) instance Monad (Reader e) where -- (>>=) :: Reader e a -> (a -> Reader e b) -> Reader e b ra >>= arb = Reader (\e -> let a = runReader ra e -- a rb = arb a -- Reader e b in runReader rb e) –------Monad Writer Permite gerar traços de execução ou logs sem que o programador gere “impurezas” no código para guardar esse tipo de informação. data Writer w a = Writer a w instance (Monoid w) => Monad (Writer w) where -- (Writer w a) -> (a -> Writer w b) -> (Writer w b) (Writer a w) >>= k = let (b, w') = runWriter (k a) in Writer b (w <> w') –------Monad State Lida com casos em que recebemos um estado mas as funções que executamos retornam outro estados diferentes. data State s a = State (s -> (a, s)) instance Monad (State s) where -- (>>=) :: State s a -> (a -> State s b) -> State s b sa >>= f = State (\s -> let (a, s1) = runState sa s sb = f a in runState sb s1) –------Monad IO Lida com com os efeitos que as entradas e saídas podem ter no pureza de funções, existe a Monad IO, que encapsula resultados “impuros”, de computações interativas. newtype IO a = newtype ST a = State -> (a, State) type State = Environment Funções de entrada e saída: IO actions –------High-Order Functions Analogamente às para funções, há em Control.Monad funções de alta ordem para Monads, tais como filterM e mapM.
5 BRUNA ISHIDA Monads são um tipo de estratégia para resolver algum problema que se repete com frequência. Existem alguns tipos diferentes de Monads, como por exemplo: - Monad Reader: uma boa implementação para a passagem implícita de informação de configuração entre as computações de um algorítmo. Muito útil quando é necessário realizar uma computação em diversos locais diferentes do código com diferentes valores. Possuem uma relação muito parecida com a Injeção de Dependências utilizada em programação orientada a objetos. - Monad Writer: Ela representa computações que necessitarão "stremar" um data adicionado a valores computados. Utilizados normalmente por geradores de código para emissão de código. - Monad State: A possibilidade de lidar com problemas de estado enquanto se mantém o código limpo e "puro". O mesmo envolve computações nos contextos de leitura e modificação do estado de um objeto global, ela junta duas operações de um método intuitivo. Primeiramente determina que estado deve ter depois da primeira operação e então, resolve a segunda operação com o novo estado. - Monad IO: Objetos do tipo IO podem ser vistos como contendo o estado atual do mundo fora do programa, ou seja, funções de entrada e saída que alteram de alguma maneira o estado atual do sistema. Um bom exemplo são as capturas de dados (getChar...) Existem funções de alta ordem para os Monads, que existem na biblioteca Control.Monad. Com o mesmo é possível implementar diversos métodos "monádicos", como por exemplo: filterM que é um filter, mapM que é um map
6 BRUNA MIRELLI XAVIER GONCALVES 11.5 Monad Reader Dado um tipo de dado que encapsula uma função de e para a. Sendo "e" o environment. data Reader e a = Reader (e -> a) instance Monad (Reader e) where -- (>>=) :: Reader e a -> (a -> Reader e b) -> Reader e b ra >>= arb = Reader (\e -> let a = runReader ra e -- Extraindo "a" rb = arb a -- Aplicando a função "arb" ao "a" e cria um Reader e b in runReader rb e) -- Executa o Reader rb no ambiente e -- No fundo temos que (\e -> b), que é o Reader e b 11.6 Monad Writer Seja o tipo de dado: data Writer w a = Writer a w -- Uma informação do tipo a, e um log de informação de um tipo w deriving Show instance (Monoid w) => Monad (Writer w) where -- Assinatura do bind: (Writer w a) -> (a -> Writer w b) -> (Writer w b) -- k: função que recebe a e devolve Writer w b (Writer a w) >>= k = let (b, w') = runWriter (k a) -- captura um b e um w' que veio do Writer in Writer b (w <> w') 11.7 Monad State Definido por uma função que, a partir do estado s, devolve uma tupla (a, s), onde a é um valor a definido por aquele e um novo estado. data State s a = State (s -> (a, s)) deriving Show instance Monad (State s) where -- (>>=) :: State s a -> (a -> State s b) -> State s b sa >>= f = State (\s -> let (a, s1) = runState sa s sb = f a in runState sb s1) 11.8 Monad IO newtype IO a = newtype ST a = State -> (a, State) type State = Environment Funções de entrada e saída: IO actions 11.9 Monads: Funções de Alta Ordem A biblioteca Control.Monad oferece versões de funções de alta ordem para Monads, como mapM, filterM, etc.
7 BRUNO STORER FRANCO MARTINS Como visto na semana passada funções não puras podem ser necessárias em haskell e seus principais usos estão no uso para parcialidade (em funções que podem não terminar), não-determinismo (quando funções podem retornar diversos valores para uma mesma entrada), efeitos colaterais, exceções , continuações e IOS. Além disso, Monads são usados para lidar com todos esses casos. Continuando de onde paramos semana passada, se toda função passar a receber um argumento adicional Config e estabelecendo-se uma configuração global. No exemplo do twitter dado em aula ficaria: data Config = Conf { tweet_key :: String , api_secret :: String } Dessa forma a config pode atuar ajudando com problemas "Ready-Only", para funções que necessitam das informações. Para isso so faltaria definir o tipo: data Reader e a = Reader (e -> a) postTweet :: String -> Reader Config () valida :: String -> Reader Config Bool É necessario declarar também um applicative para lidar com Reader. Quando procuramos fazer resolver um problema Write-Only o caminho é declarar a classe Writer e utiliza-la em applicatives e functors próprios. data Writer w a = Writer a w runWriter :: Writer w a -> (a, w) runWriter (Writer a w) = (a, w) tell :: w -> Writer w () tell s = Writer () s Mas pode ocorrer casos em que se é desejado escrever e ler. Pode-se usar: data State s a = State (s -> (a, s)) State se trata de um transformador de estado, que pode ser visto como uma "caixa" que recebe um estado e retorna um valor e um novo estado. Mas pode haver variações, como um transformador de estado em um estado: runState :: State s a -> s -> (a, s) runState (State f) s = f s Por fim, instâncias de Functor, Applicative, Monad devem ser semelhantes com a do Reader.
8 CAIO ARGENTINO DE OLIVEIRA
4 CAIO HENRIQUE DOS SANTOS RIBEIRO
10 EDUARDO MACIEL DE SOUZA Nessa semna vimos a continuação do assunto de Monads, abordando o uso de Monadas Read Only, Write Only, Estados, IO e funções de alta ordem. Em Read Only e Write Only vimos como podemos usar a classe Monad para tratar de funções que necessitam ler alguma informação do ambiente ou adicionar alguma informação no ambiente. Essas tarefas são muito importantes pois constantemente devemos realizar tais ações impuras e a classe Monad nos fornece essa ponte. Com Read e Write combinados podemos implementar máquinas de estados, que podem receber uma informação do ambiente e valores, executam uma ação que depende das duas entradas e por fim retona o resultado esperado e o ambiente atualizado. Usando esses conhecimentos podemos elaborar funções como getChar, getLine, putStr e putStrLn que são funções que implentar os conceitos de Reader e Write para conseguir interagir com o usuário, usando valores para as operações que não são "fornecidas" no código mas sim do ambiente. Por fim vimos as Funções de alta ordem com Monads, assim podemos usar as instâncias de Monads com funções de alta ordem, como o filterM. Onde podemos realizar um filter em uma lista e com o uso do Monad Writer receber, além da lista filtrada, um "ambiente" com o resultado do criterio de seleção para todo elemento dessa lista filtrada.
15 GABRIEL ALBANO SANTOS
11 GABRIEL DE MELLO FIALI Monads (Cont.): - Efeitos colaterais: - Read-only: se encarregam do recebimento de dados a partir de um parâmetro de entrada de usuário ou arquivo externo, por exemplo. Utiliza-se do tipo Reader. - Write-only: permite repassar os efeitos colaterais durante o processo ao retirar do contexto do tipo especificado, durante a composição de funções. Utiliza-se do tipo Writer. - Read/Write: - Combina as características do Reader (retorno a partir de uma variável de estado) e Writer (devolução de tupla). - State: é o tipo correspondente para Read/Write. - Recebe como entrada um valor de parâmetro e um estado, retornando um novo valor (que pode ser ou não do mesmo tipo) e uma atualização do estado como saída. - Sua instância de Functor é responsável por tranformar o valor encapsulado, sem alterar o estado ambiente, ou efeito colateral, da mesma forma como no Writer. - Sua instância de Applicative permite combinar computações de valores puros (de forma a não alterar efeitos colaterais), com aplicações (que permite gerar novos estados). - IO: Impureza na forma de alterações do estado do sistema. - Tipo IO consiste em modificações do tipo State. - Algumas funções de IO são: - getChar: recebe o ambiente atual e retorna o caracter capturado e o ambiente modificado. - putChar: recebe um caractere e o ambiente atual, retornando o ambiente modificado agregado a um (). - getStr: recebe o ambiente atual e retorna a string capturada e o ambiente modificado. - putStr: recebe uma string e o ambiente atual, retornando o ambiente modificado agregado a um (). - Funções de alta ordem: - Disponíveis na biblioteca Control.Monad. - mapM: recebe um monad m, uma função (a->b) e uma lista [a] para retornar um monad de [a]. - Anterior à implementação do traverse. - filterM: recebe um monad m, uma função (a-> monad de Bool) e uma lista [a] para retornar um monad de [a]. *Ambas se utilizam de recursão para operar.
13 GABRIEL MENDONÇA FARIAS Mesmo dentro da linguagem Haskell, algumas funções ainda podem ser consideradas como impuras, de modo que, por exemplo, uma função não termine, ou ao inserir o mesmo valor de entrada duas vezes, a resposta não seja exatamente igual. Ainda assim, é possível que o efeito colateral seja algo desejado, como no caso de write.only, onde o efeito colateral é uma String. Ou criar funções de estado, na intenção de que a cada vez que uma variável for usada, ela mude seu estado. A mudança de estado em Haskell pode ser explicada através de um “transformador de estado”, nele há um estado de entrada (ou um estado e um valor para interagir), que retornará um valor e um novo estado. Um Functor ST, é como uma caixa de estado, que recebe um estado e retorna um valor e um novo estado, sendo que nesta saída, se aplica uma função g ao valor, resultando ao final, na saída do novo estado, e na função g do valor resultante. A função pure, pode ser vista como um transformador de estados que não altera o estado, recebendo e devolvendo o valor e o estado recebidos na entrada. O operador (<*>) pode ser representado como um Functor ST, onde na saída do novo estado fica a entrada de outro transformador de estados e o novo valor resultante se torna o valor que receberá a função f (o valor resultante do primeiro Functor ST). Gerando duas saídas, a função f v e s’’ (função do segundo valor pelo primeiro e o segundo estado) Funções de entrada e saída são impuras, pois alteram seu estado no processo. As funções de entrada e saída são chamadas de ações IO. Também existem funções de alta ordem com versões para Monads, que podem ser acessadas através da biblioteca Control.Monad
14 GABRIEL MURAKAMI ALVES
17 GEORGE HARRISON ROCHA • Monads (continuação) - Nessa semana continuamos com os estudos de Monads, iniciados na semana passada; - Nessa semana vimos aplicações de: - Monad Reader; - Monad Writer; - Monad State; - Monad IO; - Funções de Alta Ordem para Monads; - mapM - filterM
34 GIOVANNA NOGUEIRA
18 GUILHERME FERREIRA GALDINO Monads e Efeitos Read Only Estrutura reader que recebe um parametro chamado de ambiente e retorna um valor dado este ambiente. data Reader e a = Reader (e -> a) Instancia de Functor, Applicative e Monad instance Functor (Reader e) where fmap f (Reader g) = Reader (f.g) runReader :: Reader e a -> e -> a runReader (Reader f) e = f e instance Applicative (Reader e) where pure x = Reader (\e -> x) rab <*> ra = Reader (\e -> let fab = runReader rab e fa = runReader ra e in fab fa) instance Monad (Reader e) where ra >>= arb = Reader (\e -> let a = runReader ra e rb = arb a in runReader rb e) Write Only Estrutura que permite tracear a execução das funções na sequência em que são chamadas. data Writer w a = Writer a w Instancia de Functor, Applicative e Monad instance (Monoid w) => Functor (Writer w) where fmap f (Writer a w) = Writer (f a) w instance (Monoid w) => Applicative (Writer w) where pure x = Writer x mempty -- Concatena os efeitos colaterais (w). Por isso w deve ser um Monoid. (Writer f m1) <*> (Writer a m2) = Writer (f a) (m1 <> m2) runWriter :: Writer w a -> (a, w) runWriter (Writer a w) = (a, w) instance (Monoid w) => Monad (Writer w) where (Writer a w) >>= k = let (b, w') = runWriter (k a) in Writer b (w <> w') Existe um operador chamado de peixe (fish operator >=>), que seria a composição de monads. (>=>) :: (a -> m b) -> (b -> m c) -> (a -> m c) Read and Write Transformador de Estado Uma estrutura que recebe um estado e retorna um novo estado e um valor data State s a = State (s -> (a, s)) Instancia de Functor, Applicative e Monad instance Functor (State s) where fmap f (State g) = State (\s -> let (a, s') = g s in (f a, s')) instance Applicative (State s) where pure x = State (\s -> (x, s)) instance Monad (State s) where sa >>= f = State (\s -> let (a, s1) = runState sa s sb = f a in runState sb s1) IO Funções de entrada e saída de dados são impuras pois alteram o estado atual do sistema. getchar :: IO Char putChar :: Char -> IO () main = do letter <- getChar putChar letter Funcoes de Alta Ordem para Monads mapM :: Monad m => (a -> m b) -> [a] -> m [b] filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] > mapM conv "1234" Just [1,2,3,4] > mapM conv "12a4" Nothing > filterM (\x -> [True, False]) [1,2,3] [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]]
16 GaMendes Nessa semana vimos mais sobre Monads. A primeira coisa nova que vimos foi sobre os Monads read only, que podem ser usadas para guardar informações de consulta. A instância de um exemplo da Monad ficaria assim: data Reader e a = Reader (e -> a) instance Monad (Reader e) where -- (>>=) :: Reader e a -> (a -> Reader e b) -> Reader e b ra >>= arb = Reader (\e -> let a = runReader ra e -- a rb = arb a -- Reader e b in runReader rb e) Depois vimos sobre a Monad Writer permite criarmos um traço de execução sem a necessidade de criar boilerplate code para tratar dessa funcionalidade. A instância de um exemplo da Monad, ficaria assim: instance (Monoid w) => Monad (Writer w) where -- (Writer w a) -> (a -> Writer w b) -> (Writer w b) (Writer a w) >>= k = let (b, w') = runWriter (k a) in Writer b (w <> w') A Monad State permite definirmos um estado de leitura e escrita que é atualizado durante a execução de uma função. Para isso combinamos instâncias dos dois tipos de Monads anteriores, e usamos essas instâncias para realizar operações de gravação e manipulação de estados.
20 HEBER CAMACHO DESTERRO
19 HENRIQUE AUGUSTO DE OLIVEIRA As funções impuras são implementas para ocasiões como Parcialidade, Não-determinismo, Read only, Write Only, Read/Write, Exceções, Continuações e Entrada/Saída. Parcialidade: A parcialidade deve ser utilizada quando temos uma função que pode não terminar Não-determinismo: O não-determinismo é semalhante a uma função que retorna uma lista de resultados diferentes dependendo de diversas condições. Uma forma de fazer o modelo de não-determinismo é através do uso de listas. Exceções: Quando utilizamos funções que retornam exceções, quando que, para determinados valores, aquela função não retorna nenhum resultado válido. Maybe é muito utilizado para esses casos. Read Only: Diz respeito a uma função que tem apenas acesso a leitura de um estado externo ou mesmo ambiente. Um exemplo clássico para Read-Only é o uso do tipo Reader que faz um tratamento específico em um ambiente. Write Only: para exemplos de logs, são utilizados esse tipo de função, fazendo um desenvelopamento do dado. Read and Write: Operaçãoes utilizadas para realizar recursos de escritas e leituras, não fazendo uma dessas funções de forma isolada. O exemplo clássico seria o gerador de estados. Entrada/Saída: Funções de Entrada/Saída são impuras também pois alteram o sistema do sistema. Tanto entradas feitas por usuários ou sistemas, mas também os I/O monads são possíveis para interagir com o ambiente fora a sistema.
21 HENRIQUE FANTATO SILVA DE ALBUQUERQUE Para resolver problemas onde certas combinações de valores em uma função são proibidas, como por exemplo, qualquer inteiro dividido por 0 não possui resultado, podemos usar um tipo Maybe. Porém, ao utilizarmos desse tipo de dados, não podemos mais criar diretamente uma instância de Applicative, pois essa instância é para computações que tem partes independentes entre si, mas queremos agora algo que dependa de um resultado anterior. Para isso, utilizamos o operador bind (>>=). O Monad pode ser visto como um Monoid dos Functors, onde o elemento identidade é o return, e o operador associativo é uma variação do bind, com a assinatura: (>=>) ::Monad m=> (a -> m b) -> (b -> m c) -> (a -> m c) Basicamente, duas funções do tipo (a -> Monad a) podem ser combinadas gerando uma terceira função resultante (c -> Monad c). Além dessa possibilidade de utilizar instâncias de Applicative em tipo de dados com efeitos, o monad também é aplicado para tratar exceções, não-determinismo, parcialidades, efeitos colaterais e estados!
44 HENRIQUE MAGRO DE SOUZA
23 LEANDRO RIBEIRO DE ALMEIDA
39 LOUIS PHILLIPE SARDA DUBOIS Transformador de estado: Dada a função para aplicar um transformador de estado: runState :: State s a -> s -> (a, s) runState (State f) s = f s Podemos definir sua instância de Monad como: instance Monad (State s) where -- (>>=) :: State s a -> (a -> State s b) -> State s b sa >>= f = State (\s -> let (a, s1) = runState sa s sb = f a in runState sb s1) Isso é útil quando queremos gerar novos transformadores de estado dependendo do valor retornado do outro. Efeitos colaterais (Entrada e saída): Funções de entrada e saída são impuras, a função getChar por exemplo se executada duas vezes, o valor não necessáriamente é igual. O mesmo pode ser dito para a função putChar. Basicamente, as funções de entrada e saída alteram estado, e podemos defini-las da seguinte maneira: newtype IO a = newtype ST a = State -> (a, State) type State = Environment Com isso se fizermos: getchar :: IO Char putChar :: Char -> IO () do putChar 'a' putChar 'a' na verdade estaremos fazendo: (_, env') = putChar 'a' env (_, env'') = putChar 'a' env' Essas funções de entrada e saída são chamadas de ações de IO (IO actions).
26 LUCAS DAVID VADILHO # Semana 8 ## Monad Reader > So how do we use this? Well, the reader monad is good for passing (implicit) configuration information through a computation. > > Any time you have a "constant" in a computation that you need at various points, but really you would like to be able to perform the same computation with different values, then you should use a reader monad. > > Reader monads are also used to do what the OO people call dependency injection. For example, the negamax algorithm [...] The algorithm itself though does not care what game you are playing [...] > > https://stackoverflow.com/questions/14178889/what-is-the-purpose-of-the-reader-monad
25 LUCAS SILVA AMORIM
27 LUCAS YUDI FUKAZAWA CASSIN Read-Only Funções responsáveis pela leitura de "chaves" em tipos, de "objetos"... Utilização de Monad para facilitação Utilizado para leitura do "estado" atual, por exemplo. Write-Only Funções reponsáveis por escrver algo, como deixar um traço de log. Também utiliza-se de Monads para facilitação Utilizado para escrever um novo estado, por exemplo. Read-Write A combinação das duas acima Utilizado para alterar estados conforme a o estado recebido, por exemplo. IO Funções que alteram o "Mundo" em que o código está rodando Como escrever na tela por exemplo, ou capturar informações do teclado de arquivos...
22 LUCAS ZOCCHIO Como já fora falado na semana anterior, os Monads são uma classe de tipo que permite cooncatenar funções que geram um efeito colateral, de modo que o resultado da aplicação de uma função dependende do efeito colateral gerado pela função anterior. Essa classe de tipos é útil quando queremos tratar de situações que envolvem efeitos colaterais, como exceções, leituras e escritas, e entrada e saída interativas. O tipo Status combina a leitura e a escrita de dados, pois armazena uma função que recebe um valor, executa uma operação e escreve numa String. Tanto no caso da leitura, como da escrita ou da mudança de um estado, é possível usar Monads para simplificar a implementação de funções que envolvem essa combinação de efeitos colaterais. Como o "bind" (>>=) realiza a concatenação de um efeito anterior com a nova função a ser aplicada, é possível passar ordens suscessivas ao programa, cada uma dependendo do estado anterior. As entradas e saídas interativas são feitas pelo tipo IO, que é um Monad, já que cada leitura envolve o recebimento de informação de uma variável de estado (o ambiente computacional naquele momento) e cada escrita altera essa mesma variável de estado. Portanto para realizar leituras e escritas é preciso o operador "bind" ou a sintaxe "do". Há implementações de funções de alta ordem, como map e filter, específicas para Monads na bilbioteca Control.Monads. Com essas implementações é possível fazer uso das propriedades dos Monads, o que permite, por exemplo, que a função filterM gere todas as o conjunto de combinações dos elementos de uma lista, por usar uma propriedade do Monad listas, levando a uma função que retorna os possíveis retornos daquela computação.
28 LUCCA IANAGUIVARA KISANUCKI Bind (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b Operador usado para vincular um valor x ao argumento de uma função Monad Um Monoid das categorias dos Functors O elemento identidade é o return Um operador associativo (>=>), operador peixe (fish operator) (>=>) ::Monad m=> (a -> m b) -> (b -> m c) -> (a -> m c) eval :: Expr -> Maybe Int eval (Val n) = Just n eval (Div x y) = eval x >>= \n -> eval y >>= \m -> maybeDiv n m Expressão do-notation do x1 <- m1 x2 <- m2 f x1 x2 Facilita a ligibilidade eval (Div x y) = do n <- eval x m <- eval y safeDiv n m Estado data State s a = State (s -> (a, s)) Transformador de Estado REcebe um estado e retorna um valor e um novo estado Pure Transformador que não altera o estado Efeitos Colaterais IO Funções impuras para alterar o estado atual do sistema getChar - captura uma char do teclado putChar - escreve na saida padrão c <- getChar putChar c Temos tambem getLine, putStr e putStrLn Funções de Alta Ordem em Monads Disponivel na Biblioteca Control.Monad mapM, filterM
29 LUIZ FELIPE LEAL GOMES AZZOLINI
30 MARCELO CECILIO FAGUNDES DA SILVA FILHO Os monads são muito úteis para certas aplicações: Read-Only: Supondo que temos uma configuração global a qual queremos que seja aplicadas a algumas funções sem alterá-la. Para isso podemos, passar essa configuração como parâmetro para as funções. Como passar dois argumentos a e b é o mesmo que uma função a -> b podemos criar um tipo data Reader a b = Reader (a -> b). Criando uma instância de Monad para Reader, podemos facilitar as operações usando os operadores do e return, que realiza as operações sem alterar o valor da configuração global. Write-Only: Supondo que queremos realizar algumas operações e salvar os passos dados. Podemos criar um tipo data Writer w a = Writer a w. Dessa forma podemos criar uma instância de monad que realiza a operação no primeiro elemento e concatena o segundo com algum outro valor. Sendo o primeiro um valor a e o segundo o nome da operação, podemos assim, após uma série de operações, obter o valor final e um log das operações feitas. Read/Write: Juntando os dois conceitos anteriores podemos criar um tipo data State s a = State (s -> (a, s)). Dessa forma podemos criar um transformador de estados que, recebe um valor e o estado atual, realiza alguma operação e retorna um novo valor e o próximo estado. Criando um tipo IO, sendo um State que armazena os valores da tela e etc, podemos realizar operações como ler ou seja, alterando o seu estado da tela. Existem algumas funções de alta ordem para monads. Entre elas está: * mapM: Realiza o mesmo que o traverse, porém para monads ao invés de Applicative. * filterM: É semelhante ao filter porém, como a instância de listas para monads representa uma computação não determinísticas, ele filtra as possibilidades de combinações de acordo com algum parâmetro.
35 MARIANA MIWA OKUMA MIYASHIRO Efeitos colaterais: - necessário definir instâncias de Functor, Applicative e Monad - (>=>): composição de Monads - Read only: as funções conseguem "ler" o tipo de dado pro qual o Monad é criado - data Reader e a = Reader (e -> a) - runReader (Reader f) e = f e - instanciar Functor (Reader e), Applicative (Reader e) e Monad (Reader e) - Write only: para criar logs (gravar traço de execução) ou calcular custo computacional - data Writer w a = Writer a w -- w do writer representa o efeito colateral desejado - runWriter (Writer a w) = (a, w) - tell s = Writer () s - instanciar (Monoid w) => Functor (Writer w), (Monoid w) => Applicative (Writer w) e (Monoid w) => Monad (Writer w) - Read/Write: Monad State (variável de estado ou global em outras linguagens) - data State s a = State (s -> (a, s)) - transformador de estado: - recebe valor e estado, devolve valor e atualização - equivalente a Reader s (Writer s a) - runState (State f) s = f s - instance Functor (State s) where fmap f (State g) = State (\s -> let (a, s') = g s in (f a, s')) - instance Applicative (State s) where pure x = State (\s -> (x, s)) sab <*> sa = State (\s -> let (f, s1) = runState sab s (a, s2) = runState sa s1 in (f a, s2)) - instance Monad (State s) where sa >>= f = State (\s -> let (a, s1) = runState sa s sb = f a in runState sb s1) - Entrada/Saída interativa: - newtype IO a = newtype ST a = State -> (a, State) - type State = Environment - em Haskell, funções de entrada/saída = ações de IO - funções básicas: - getchar :: IO Char -- captura caractere - putChar :: Char -> IO () -- escreve na saída - return :: a -> IO a -- retorna como ação IO - possibilita funções getLine ou putStr - Funções de alta ordem: - biblioteca Control.Monad - versões de map (mapM) e filter (filterM)
31 MATHEUS ALEXANDRE DE SENA
33 NATALIA LEITE VARES DE SOUZA MONADS E EFEITOS Mesmo que o Haskell seja considerada uma linguagem puramente funcional, existe uma limite do quão puro o programa pode ser. As funções impuras são importantes para diversas situações: - Parcialidade: como quando temos uma função que pode não terminar - Não-determinismo: como quando uma função pode retornar diferentes saídas dependendo de certas condições - Exceções (função Either): como quando lidamos com funções parciais ou que geram exceções e queremos identificar qual foi o problema - Efeitos colaterais: Read only, Write only, Read/Write - Entrada e saída iterativa: pois alteram o estado atual do sistema. FUNÇÕES DE READ E WRITE Um exemplo de função read e write pode ser escrito a seguir: t -> (a -> (b, a)) t -> Reader a (Writer a b) onde o tipo Reader é a -> b, o tipo Writer é (a, b) FUNÇÕES DE ENTRADA E SAÍDA Funções de entrada e saída de dados são impuras pois alteram o estado atual do sistema. A função getChar captura um caracter do teclado. Se eu executar tal função duas vezes, o valor da função não necessariamente será igual. A função putChar escreve um caracter na saída padarão (ex.: monitor). Se eu executar duas vezes seguidas com a mesma entrada, a saída será diferente. Basicamente, as funções de entrada e saída alteram estado No Haskell chamamos as funções de entrada e saída como ações de IO ( IO actions ). As funções básicas são implementadas internamente de acordo com o Sistema Operacional, sendo essas: getChar, putChar e return FUNÇÕES DE ALTA ORDEM PARA MONADS As funções de alta ordem possuem versões para Monads na biblioteca específica Control.Monad Temos funções como map (mapM) e filter (filterM), onde a principal diferença é: - filter seleciona elementos de uma lista - filterM seleciona possíveis eventos de uma sequência de computações
32 NATHALIA CORREA DOS SANTOS Tópico 3.5 Efeitos Colaterais: Read Only O reader é uma função que encapsula (e -> a) Tópico 3.7 Efeitos Colaterais: Write Only O Write-Only pode ser utilizado para imprimirmos mensagens após a execução de funções, seja para guiar o usuário ou retornarmos logs que nos auxiliam a debugar os códigos. Na implementação de uma função que utiliza o Writer em sua assinatura vimos o uso do >=> para realizar a composição de duas funções, nesse caso realizando a composição de isEvenW' com notW'. 3.9 Efeitos Colaterais: Read and Write Para fazermos uma função que permite ler e escrever dados, podemos utilizar a composição de um Reader com um Writer. Vimos como implementar essa composição para armazenarmos estados em nossas funções. Esse transformador de estados pode ser visto como uma caixa que receve um estado e retorna um valor e um novo estado, ou então um transformador que além de um estado receve um valor que ira agir dentro desse ambiente. 3.14 Efeitos Colaterais: IO A função getchar captura um caracter do teclado, e caso seja executada a função duas vezes o valor da função não será necessariamente igual, pois o usuário pode digitar carateres diferentes. (gerando efeito colateral.) A função putchar escreve um caracter na saída padrão. Assim, as funções getchar e putchar alteram o estado. 4 Funções de alta ordem para Monads Na biblioteca Control.Monad podemos encontrar funções de alta ordem para Monads (MapM,filterM)
38 PAULO GABRIEL MASSA
36 PEDRO BRAGA DOS SANTOS BACELLAR
37 PEDRO MACHADO NERY DOS SANTOS Monads realizam operações sequencialmente tratando de efeitos. São definidas pelo operador bind (>>=) que explica como realizar tal tratamento. Applicatives têm aplicação similar, mas exigem que efeitos sejam independentes entre si. Pela similaridade, no entanto, o operador pure dos Applicatives faz parte da definição da classe Monad junto ao bind, mas com o nome de return. eval::Expr -> Maybe Int eval(Div x y) = do n <- eval x --realiza eval de x e vincula o resultado a m se diferente de Nothing m <- eval y maybeDiv n m --trata os efeitos pelas variáveis vinculadas m e n Monads podem ser vistas como Monoid de Functors, sendo return o elemento identidade e ((>=>) ::Monad m=> (a -> m b) -> (b -> m c) -> (a -> m c)) o operador associativo. Assim Monads associam funções para gerar uma terceira e possuem um elemento neutro, o que permite controle da falha de qualquer operação intermediária ao tentar fazer o bind. Isso é aplicado ao caso SafeNum visto em aula, além do caso de MaybeDiv acima, para tratamento de erro (de forma alternativa a blocos try/catch de outras linguagens, com a Monad Either ou Left/Right, por exemplo). Monads podem ser usadas para introduzir não-determinismo (a Monad de Lista pode fazê-lo tratando a relação entre conjuntos de listas, algo similar a uma list comprehension) e tratar efeitos colaterais em funções de entrada e saída (Read only, Write only, Read/Write definem o tipo do efeito colateral desejado), além de tornar mais clara a aplicação parcial de funções (o valor bottom _|_ sinaliza uma função que pode não terminar, enquanto que nas monads mais parâmetros podem ser introduzidos em funções já definidas parcialmente). O tratamento de efeitos estende a usabilidade de uma linguagem puramente funcional que em tese não os permitiria
43 PEDRO REGIO SHOJI
40 PIETRO DI CONSOLO GREGORIO Como efeitos colaterais da definição da classe Monads vista na aula anterior, temos a definição do: - tipo Reader, usado para simplificar o exemplo do tweet (Read Only); - tipo Writer, usado para apresentar o traço de execução (Write Only); - tipo State, usado para converter uma árvore para Tree Int com o numero de visitas (Read and Write); - tipos IO (State -> (a, State)) são tipos State que quando executados alteram o ambiente World, alguns exemplos são getchar e putchar. Os exemplos implementados foram as funções putStr', putStrLn' e o getLine'. A biblioteca Control.Monad possui algumas versões de alta ordem para Monads, todas as funções são marcadas com um "M" no final. Os exemplos apresentados foram o mapM e o filterM.
9 RAFAEL BRUNO FERREIRA FIGUEIREDO Monad Reader: Uma forma de criar uma estrturura de dados que pode carregar configurações (por exemplo, mas podem ser outros dados) através do código, utilizando tipos e monads para estruturar isso. A configuração fica encapsulada em um "ambiente" que pode ser tratado através das funções de monad. A equação runReader serve para desencapsulas os valores do ambiente e e permite acessar seus valores. Monad Writer: É uma forma de fazer um "log" de funções que foram aplicadas em seguida, utilizando as características dos Monads. Para fazer a instancia applicative e monad do writer deve ter a restrição de que o valor é um monoid. runWriter é uma função análoga ao reader. É uma função que "dessencapsula" do monad o resultado. Monad State: um meio de guardar estados de execução utilizando monads. Por exemplo é possível atualizar os valores a cada execução do monad. Em uma recusão (ou repetidas aplicações de funções) é possível "enviar" dentro do container o estado atual do monad para ser aplicado na execução do próximo passo de execução. A instancia applicative serve para possivelmente tratar problemas na execução. Monad IO: Entrada e saida de dados sao impuras pois alteram os estados do programa em execução. O estado completo da computação pode ser entendido como um State Monad. Da mesma forma que o state anterior, com a entrada o estado do computador muda e o valor de entrada/saida é armazenado nesse estado. Alta ordem Monad: Reforça as aplicações de computação probabilística, onde é possível tratar ocorrencias com nothing. Quando uma função monad encontra o nothing o resultado da função é sempre nothing.
41 RAFAEL PAUWELS DE MACEDO Começamos vendo o Monad Reader, que é um monad do tipo Reader e a = Reader (e -> a), esse monad permite que o programa acesse dados somente para leitura, como um arquivo de configuração por exemplo. Para construir as intâncias de Applicative e Monad usamos a sintaxe let a = ... in ... Tendo o Reader como monad conseguimos reescrever as funções postTweet e valida de forma mais natural com a notação do e sem necessidade de usar o arquivo de entrada config nos parametros da função. Logo depois vimos o uso de um Monad Writer, que seria um monad apenas de escrita. Nesse caso simulamos um log que indica o caminho pelo qual uma função passa durante a execução. O monad se encaixa bem nesse caso para que não seja necessário trafegar uma String por todos os métodos que a primeira função passa. Nesse exemplo vimos o operador >=> que age como a composição de monads, esse operador precisa ser importado de Control.Monad No nosso terceiro caso vimos como podemos representar estado usando monads através de um exemplo com árvores onde cada folha da árvore seria substituido pelo número sequencial. Esse comportamento é perfeitamente modelado através de um Reader aplicado em um Writer, com isso em mente criamos o tipo State e implementamos as instâncias de Functor, Applicative e Monad. Por fim vimos o IO, que se comporta como um State Monad sobre o computador, e algumas funções úteis do IO como getChar, putChar e algumas formas sobre como reimplementar funções IO como o getLine que pode ser escrito como getLine' = do c <- getChar if c == '\n' then return [] else (c:) <$> getLine' Vimos também funções de alta ordem para monads, por convenção terminadas em M, como mapM e filterM.
42 RAPHAEL RAMOS DA SILVA ---------------------------------------------------- Monad Reader --------------------------------------------- Ex: utilização de um argumento global (ambiente). Como tratar a impureza? data Reader e a = Reader (e -> a) postTweet :: String -> Reader Config () valida :: String -> Reader Config Bool -- Instância de Monad instance Monad (Reader e) where -- (>>=) :: Reader e a -> (a -> Reader e b) -> Reader e b ra >>= arb = Reader (\e -> let a = runReader ra e -- a rb = arb a -- Reader e b in runReader rb e) ---------------------------------------------------- Monad Writer --------------------------------------------- Ex: guardar logs (escritas) durante a execução de funções - problemas na composição de funções Como resolver? Através do Writer (+ funções auxiliares runWriter e tell) data Writer w a = Writer a w -- w representa o tipo do efeito colateral (String, no ex do log acima) runWriter :: Writer w a -> (a, w) runWriter (Writer a w) = (a, w) tell :: w -> Writer w () tell s = Writer () s -- Instância de Monad instance (Monoid w) => Monad (Writer w) where -- (Writer w a) -> (a -> Writer w b) -> (Writer w b) (Writer a w) >>= k = let (b, w') = runWriter (k a) in Writer b (w <> w') ---------------------------------------------------- Monad State ---------------------------------------------- Ex.: Alteração de estados - tratando a pureza e a imutabilidade. A utilização de Reader-Writer nos permite trabalhar com valores que podem ser lidos e alterados: t -> Reader a (Writer a b) <---> data State s a = State (s -> (a, s)) () -- A função auxiliar runState permite a transformação de estados runState :: State s a -> s -> (a, s) runState (State f) s = f s -- instância de Monad instance Monad (State s) where -- (>>=) :: State s a -> (a -> State s b) -> State s b sa >>= f = State (\s -> let (a, s1) = runState sa s sb = f a in runState sb s1) ----------------------------------------------------- Monad IO ------------------------------------------------ Lidando com funções de entrada e saída (impuras) - As funções de IO nada mais são do que um tipo State (que representa o ambiente) newTipe IO a = State World a Algumas aplicações do IO: getchar :: IO Char <=> State World Char putchar :: Char -> IO () <=> Char -> State World () return :: a -> IO a (envolve o valor no IO) Com as funções acima, conseguimos implementar outras funções de IO. -------------------------------------- Funções de Alta Ordem para Monads -------------------------------------- versões presentes na blibioteca Control.Monad -- Versão para map mapM :: Monad m => (a -> m b) -> [a] -> m [b] mapM f [] = return [] mapM f (x:xs) = do y <- f x ys <- mapM f xs return (y:ys) -- versão para filter (computação não determinística - seleciona possíveis eventos) filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] filterM p [] = return [] filterM p (x:xs) = do b <- p x ys <- filter M p xs return (if b then x:ys else ys)
24 RENAN FERREIRA LIMA O Reader é útil quando temos, por exemplo, uma configuração global compartilhada com várias funções, assim pode-se defini-lo a partir de um tipo que encapsula uma função de e para a. Para as funções que precisam acessar a função armazenada no tipo Reader, é possível implementar o runReader que é similar ao get de outras linguagens. O uso do Reader permite implementar códigos mais simplificados, diminuindo a redundância. Um outro tipo de monad é o Writer, um exemplo de aplicação é quando queremos criar um traço de execução para exibir quais funções foram utilizadas. Sem usar monads, podemos fazer isso usando let, algo que não é prático principalmente em cenários em que há diversas funções. Contudo, ao definir um tipo Writer que armazena uma informação do tipo a e um log de informação w, ao criar a instância de monoid de Writer essa informação w deve ser tratada como monoid. Assim, como foi feito com o Reader, podemos definir uma função run, no caso um runWriter que acessa os dados armazenados no Writer. Uma vez implementado o monad Writer, é possível utilizá-lo de forma prática em cenários mais complexos, eliminando a limitação apresentada inicialmente. Um outro tipo de monad é o State, em síntese, ele é uma composição do Reader e Writer. O State pode ser definido como uma função que pega um estado s e devolve uma tupla a, s, onde a é o valor definido pelo estado e s o novo estado. Um outro tipo monad abordado foi o IO, que é basicamente um tipo State, que toda vez que algo é executado, altera o estado do ambiente. É possível trabalhar com diversas funções utilizando o IO, por exemplo, getLine, putStr, entre outras. Para funções de alta ordem podemos utilizar a biblioteca Control.Monad
46 VITOR RUBENS SNIQUER LEAO MARTINS
45 VITTORIA ARIEL DOS SANTOS BOROTTO Monads: Efeitos Colaterais Suponhamos que configuração global compartilhada com todas as funções, e toda funcao passa a receber um argumento adicional com essa configuracao Aplicar currying, e definir o tipo Reader; Podemos fazer a instancia Functor para o tipo Reader E entao criar a instancia de Monad data Reader e a = Reader (e -> a) instance Monad (Reader e) where -- (>>=) :: Reader e a -> (a -> Reader e b) -> Reader e b ra >>= arb = Reader (\e -> let a = runReader ra e -- a rb = arb a -- Reader e b in runReader rb e) =>Write Only Tendo em vista: isEven x = even x not' b = not b isOdd x = (not' . isEven) x podemos criar novas versoes dessas funcoes: isEven x = (even x, " isEven ") not' b = (not b, " not' ") isOdd x = (not' . isEven) x -- ops Definindo o tipo Writes e algumas funcoes auxiliares temos: data Writer w a = Writer a w runWriter :: Writer w a -> (a, w) runWriter (Writer a w) = (a, w) tell :: w -> Writer w () tell s = Writer () s Note: o w do Writer representa o tipo de efeito desejado, que nesse caso é a string temos o Monad Writer: instance (Monoid w) => Monad (Writer w) where -- (Writer w a) -> (a -> Writer w b) -> (Writer w b) (Writer a w) >>= k = let (b, w') = runWriter (k a) in Writer b (w <> w') =>Estado e transformador de estado: Quando queremos que n seja uma variável de estado em uma arvore, toda vez que a utilizarmos ela altere seu estado! Mas somos puros e imutáveis! Para isso precisamos incorporar o estado atual na declaração Um transformador de estado pode ser entendido como uma caixa que recebe um estado e retorna um valor e um novo estado =>Efeito IO:basicamente, as funções de entrada e saída alteram estado newtype IO a = newtype ST a = State -> (a, State)
47 WESLEY AXEL DE BARROS Para esta semana 08, tivemos a segunda parte de um topico muito importante para o estudo de Haskell na disciplina de Paradigmas de Programação. Estudamos a segunda parte do conceito de Monads, aonde vimos o Monad Reader, que é uma monada que permite que uma função que "leia" esta monada passe suas variaveis implicitas dentro dessa monada. Permitindo assim criar uma possivel "variavel global". Vimos o Monad Writer, que é uma monada que permite que varias funções sejam concatenadas, e que seja possivel gravar o traço de execução das mesmas. Verificamos o Monad State, que é uma monada que permite que armazenar um estado de uma função por exemplo, e transformar o estado através de outras funções. Vimos o que é o Monad IO, que é uma monada que permite armazenar em estados variaveis vindas do sistemas, ou seja, variaveis digitadas por exemplo em um teclado na execução do progama. E vimos por ultimo as funções de alta ordem para monadas, que são as funções já utilizadas no da disciplina como map,filter, mas desenvolvidas para trabalhar com Monadas que armazenam estados.
48 WILLIAM SENA SILVA
12 francesquini