O documento discute o paradigma funcional de programação e linguagens funcionais. Ele apresenta os problemas da crise do software e como as linguagens funcionais podem ajudar a resolvê-los, permitindo programas mais claros, concisos e seguros. Em seguida, explica os conceitos-chave de programação funcional e fornece exemplos nas linguagens Haskell e Lisp.
[1] O documento descreve elementos básicos de algoritmos como variáveis, tipos de dados, operadores, funções e estruturas de controle.
[2] São apresentados tipos de dados como inteiro, real, caractere e lógico, e operadores aritméticos, relacionais e lógicos.
[3] Estruturas de controle como condicionais simples e compostas e repetições por condição e contagem são explicadas com exemplos de algoritmos.
Este documento apresenta instruções básicas de saída em Visualg, incluindo escreva(), escreval() e limpatela(). A instrução escreva() imprime texto na tela, escreval() faz o mesmo e pula linha, e limpatela() limpa a tela. Exemplos de sintaxe e fluxogramas são fornecidos para cada instrução.
O documento fornece uma introdução aos sistemas operativos, definindo-os como um conjunto de programas que permitem a interação entre o usuário, hardware e aplicativos. Explora conceitos-chave como processos, memória, arquivos e periféricos, e classifica sistemas operativos de acordo com fatores como número de usuários e programação simultânea.
O documento apresenta uma lista de 31 exercícios de programação em Java sobre vários tópicos como entrada e saída de dados, cálculos matemáticos, condicionais e repetições. Os exercícios vão desde operações simples como soma e subtração até cálculos mais complexos envolvendo salários, descontos e ordenação de dados.
Descritiva Narrativa (Lógica de Programação)Gercélia Ramos
Existem diversas formas de se representar um algoritmo, neste slide estaremos falando sobre a Descritiva Narrativa onde descrevemos o passo-a-passo de um algoritmo.[Aula para curso técnico]
O documento descreve diferentes tipos de memórias não voláteis, incluindo ROM, PROM, EPROM, EEPROM e memória flash. A ROM é apenas de leitura, enquanto a PROM pode ser programada uma vez. A EPROM mantém dados por anos e pode ser lida ilimitadas vezes, e a EEPROM pode ser apagada e programada várias vezes, embora com um limite. A memória flash armazena grandes quantidades de dados e é usada em dispositivos portáteis.
O documento apresenta os principais conceitos de computação, incluindo a história dos computadores desde o ábaco até as gerações modernas, a arquitetura de Von Neumann e seus componentes centrais, e explora o funcionamento de componentes como CPU, memória e entrada/saída.
[1] O documento descreve elementos básicos de algoritmos como variáveis, tipos de dados, operadores, funções e estruturas de controle.
[2] São apresentados tipos de dados como inteiro, real, caractere e lógico, e operadores aritméticos, relacionais e lógicos.
[3] Estruturas de controle como condicionais simples e compostas e repetições por condição e contagem são explicadas com exemplos de algoritmos.
Este documento apresenta instruções básicas de saída em Visualg, incluindo escreva(), escreval() e limpatela(). A instrução escreva() imprime texto na tela, escreval() faz o mesmo e pula linha, e limpatela() limpa a tela. Exemplos de sintaxe e fluxogramas são fornecidos para cada instrução.
O documento fornece uma introdução aos sistemas operativos, definindo-os como um conjunto de programas que permitem a interação entre o usuário, hardware e aplicativos. Explora conceitos-chave como processos, memória, arquivos e periféricos, e classifica sistemas operativos de acordo com fatores como número de usuários e programação simultânea.
O documento apresenta uma lista de 31 exercícios de programação em Java sobre vários tópicos como entrada e saída de dados, cálculos matemáticos, condicionais e repetições. Os exercícios vão desde operações simples como soma e subtração até cálculos mais complexos envolvendo salários, descontos e ordenação de dados.
Descritiva Narrativa (Lógica de Programação)Gercélia Ramos
Existem diversas formas de se representar um algoritmo, neste slide estaremos falando sobre a Descritiva Narrativa onde descrevemos o passo-a-passo de um algoritmo.[Aula para curso técnico]
O documento descreve diferentes tipos de memórias não voláteis, incluindo ROM, PROM, EPROM, EEPROM e memória flash. A ROM é apenas de leitura, enquanto a PROM pode ser programada uma vez. A EPROM mantém dados por anos e pode ser lida ilimitadas vezes, e a EEPROM pode ser apagada e programada várias vezes, embora com um limite. A memória flash armazena grandes quantidades de dados e é usada em dispositivos portáteis.
O documento apresenta os principais conceitos de computação, incluindo a história dos computadores desde o ábaco até as gerações modernas, a arquitetura de Von Neumann e seus componentes centrais, e explora o funcionamento de componentes como CPU, memória e entrada/saída.
O documento fornece uma introdução básica sobre computadores, incluindo:
1) O que é um computador e seus principais componentes;
2) Diferentes tipos de sistemas operacionais e softwares;
3) Como ligar e desligar um computador corretamente.
O documento discute os principais tipos de memórias ROM e RAM, incluindo suas características e aplicações. Apresenta as memórias RAM como sendo voláteis e usadas para armazenar dados durante a execução de programas, enquanto as memórias ROM são não voláteis e permitem apenas leitura dos dados.
O documento discute o que é um sistema operacional e suas principais funções. Um sistema operacional serve como interface entre o hardware e o software, controlando o fluxo de dados e recursos. Ele deve prover conveniência, eficiência e possibilidade de evolução para os usuários. O sistema operacional é a camada mais baixa de software e suporta programas e utilitários.
Lista de Exerícios - Manutenção e Redes de Computadores IFNMG - Campus JanuáriaSuzana Viana Mota
Lista de exercícios da disciplina de Manutenção e Redes de Computadores do IFNMG - Campus Januária.
Referente aos conteúdos: - Placa Mãe, Processadores, HD's, Memória RAM, Memória ROM e Memória Cache. Montagem e manutenção de microcomputadores
O documento discute estruturas de decisão em algoritmos, explicando os comandos "SE", "SE ENTÃO", "SE ENTÃO SENÃO", e dá exemplos de como implementá-los em diagramas de blocos e pseudo código.
O documento descreve um enigma sobre um prisioneiro preso em uma cela com duas saídas, cada uma vigiada por um guarda, sendo que um guarda sempre diz a verdade e o outro sempre mente. Para descobrir qual a saída correta, o prisioneiro deve fazer uma única pergunta a um dos guardas escolhidos aleatoriamente.
1. O documento apresenta 8 exercícios sobre laços de repetição em algoritmos. Os exercícios pedem para ler valores e calcular médias, máximos, mínimos e outras estatísticas.
1) Um fluxograma representa algoritmos usando formas geométricas para diferentes ações. Isso facilita a compreensão das ideias nos algoritmos.
2) Fluxogramas devem ser claros, simples e de fácil leitura, sem ambiguidades.
3) Fluxos descrevem sistemas de cima para baixo ou esquerda para direita.
O documento lista e descreve vários utilitários e ferramentas do sistema operacional Windows, incluindo o Bloco de Notas, WordPad, Calculadora, Windows Media Player, WinRAR, Acrobat Reader e antivírus. Ele também fornece atividades para usar esses utilitários e discute desfragmentação e outros recursos do sistema.
Este documento apresenta conceitos sobre algoritmos, incluindo: (1) a definição de algoritmo como um conjunto de regras para resolver um problema específico; (2) a necessidade de algoritmos para que computadores possam executar tarefas; (3) as formas de apresentação de algoritmos incluindo linguagem natural, fluxograma e pseudo-código.
O documento explica os diferentes tipos de barramentos em um computador e suas funções. Os principais barramentos conectam o processador, memória e periféricos e incluem o barramento do processador, de cache e de memória. Os barramentos de entrada e saída, como PCI, USB e SATA, conectam dispositivos como placas de vídeo, HDs e impressoras.
O documento apresenta um resumo de 14 aulas com exercícios sobre o Microsoft Excel. Cada aula contém de 1 a 3 exercícios relacionados a criação e formatação de planilhas, uso de fórmulas e funções, e criação de gráficos.
Lista de exercicios algoritmos com pseudocodigoMauro Pereira
1) O documento apresenta uma lista de exercícios de algoritmos com pseudocódigo para os alunos do curso de Eletrônica Integrado sobre estruturas sequenciais, condicionais e de repetição.
2) Os exercícios incluem algoritmos para calcular área de retângulo, trocar valores de variáveis, calcular raízes de equação de 2o grau e custo de combustível.
3) Também pede algoritmos para analisar número como positivo, negativo ou zero e tipo de triângulo.
1) O documento descreve as etapas da inicialização de um sistema operacional, incluindo a execução do POST pela BIOS, a leitura do MBR pelo BIOS e o carregamento do núcleo do sistema operacional.
2) É explicado que o MBR contém informações sobre as partições do disco rígido que permitem ao BIOS carregar o código de inicialização da partição de boot.
3) As principais etapas da inicialização são a execução do POST pela BIOS, a leitura do MBR para identificar a partição de boot e o
O documento discute variáveis em programação, definindo-as como áreas da memória que armazenam dados e informações. Explica que variáveis podem ser globais ou locais e de diferentes tipos, como inteiros, reais e lógicos. Também apresenta os operadores aritméticos, relacionais e lógicos e introduz as linguagens Portugol e G-Portugol.
O documento discute o gerenciamento de arquivos e pastas no Windows e Linux. Ele explica como arquivos são salvos em pastas e como o Windows Explorer e o Konqueror (no Linux) podem ser usados para gerenciar arquivos e pastas. Também descreve as principais configurações de pastas e arquivos que podem ser ajustadas no Painel de Controle do Windows.
O documento apresenta uma introdução sobre JavaScript, explicando porque estudar a linguagem, o que pode ser feito com ela e como iniciar o estudo. É destacado que JavaScript permite adicionar comportamento interativo às páginas web e que pode ser usada para manipular conteúdo, eventos e dados.
O documento descreve as funções e ferramentas do Windows Explorer para gerenciamento de arquivos e pastas, incluindo como criar, renomear e navegar entre pastas, além de operações básicas como copiar, colar e excluir arquivos. Também menciona alguns programas que lidam com arquivos, como Bloco de Notas e Paint.
A placa-mãe conecta todos os componentes do computador, incluindo o processador, memória RAM, disco rígido e outros. Ela contém slots para expansão, conectores para periféricos e chips responsáveis por controlar a comunicação entre componentes.
Este documento discute conceitos gerais sobre sistemas de informação. Resume os principais tipos de sistemas como sistemas transacionais, sistemas de informações gerenciais e sistemas de apoio à decisão. Também define objetivos organizacionais comuns de sistemas de informação como excelência operacional, novos produtos e serviços, melhores relacionamentos com clientes e fornecedores e melhor tomada de decisões.
O documento apresenta circuitos lógicos digitais combinacionais, incluindo somadores, subtratores, decodificadores, codificadores, multiplexadores e demultiplexadores. Circuitos como meio somador, somador completo, decodificador 2x4 e multiplexador 8x1 são explicados com diagramas mostrando suas entradas e saídas. Tópicos como adição binária, subtração binária usando complemento de 2 e aplicações de multiplexadores e demultiplexadores também são brevemente descritos.
O documento descreve a história da Internet e da World Wide Web. Começa com uma introdução sobre o que é a Internet e sua abrangência atual. Em seguida, explica que a Internet surgiu da necessidade dos EUA de comunicação durante a Guerra Fria, dando origem à ARPANET. Por fim, destaca a importância fundamental da Internet e da WWW para a sociedade e empresas modernas.
O documento fornece uma introdução básica sobre computadores, incluindo:
1) O que é um computador e seus principais componentes;
2) Diferentes tipos de sistemas operacionais e softwares;
3) Como ligar e desligar um computador corretamente.
O documento discute os principais tipos de memórias ROM e RAM, incluindo suas características e aplicações. Apresenta as memórias RAM como sendo voláteis e usadas para armazenar dados durante a execução de programas, enquanto as memórias ROM são não voláteis e permitem apenas leitura dos dados.
O documento discute o que é um sistema operacional e suas principais funções. Um sistema operacional serve como interface entre o hardware e o software, controlando o fluxo de dados e recursos. Ele deve prover conveniência, eficiência e possibilidade de evolução para os usuários. O sistema operacional é a camada mais baixa de software e suporta programas e utilitários.
Lista de Exerícios - Manutenção e Redes de Computadores IFNMG - Campus JanuáriaSuzana Viana Mota
Lista de exercícios da disciplina de Manutenção e Redes de Computadores do IFNMG - Campus Januária.
Referente aos conteúdos: - Placa Mãe, Processadores, HD's, Memória RAM, Memória ROM e Memória Cache. Montagem e manutenção de microcomputadores
O documento discute estruturas de decisão em algoritmos, explicando os comandos "SE", "SE ENTÃO", "SE ENTÃO SENÃO", e dá exemplos de como implementá-los em diagramas de blocos e pseudo código.
O documento descreve um enigma sobre um prisioneiro preso em uma cela com duas saídas, cada uma vigiada por um guarda, sendo que um guarda sempre diz a verdade e o outro sempre mente. Para descobrir qual a saída correta, o prisioneiro deve fazer uma única pergunta a um dos guardas escolhidos aleatoriamente.
1. O documento apresenta 8 exercícios sobre laços de repetição em algoritmos. Os exercícios pedem para ler valores e calcular médias, máximos, mínimos e outras estatísticas.
1) Um fluxograma representa algoritmos usando formas geométricas para diferentes ações. Isso facilita a compreensão das ideias nos algoritmos.
2) Fluxogramas devem ser claros, simples e de fácil leitura, sem ambiguidades.
3) Fluxos descrevem sistemas de cima para baixo ou esquerda para direita.
O documento lista e descreve vários utilitários e ferramentas do sistema operacional Windows, incluindo o Bloco de Notas, WordPad, Calculadora, Windows Media Player, WinRAR, Acrobat Reader e antivírus. Ele também fornece atividades para usar esses utilitários e discute desfragmentação e outros recursos do sistema.
Este documento apresenta conceitos sobre algoritmos, incluindo: (1) a definição de algoritmo como um conjunto de regras para resolver um problema específico; (2) a necessidade de algoritmos para que computadores possam executar tarefas; (3) as formas de apresentação de algoritmos incluindo linguagem natural, fluxograma e pseudo-código.
O documento explica os diferentes tipos de barramentos em um computador e suas funções. Os principais barramentos conectam o processador, memória e periféricos e incluem o barramento do processador, de cache e de memória. Os barramentos de entrada e saída, como PCI, USB e SATA, conectam dispositivos como placas de vídeo, HDs e impressoras.
O documento apresenta um resumo de 14 aulas com exercícios sobre o Microsoft Excel. Cada aula contém de 1 a 3 exercícios relacionados a criação e formatação de planilhas, uso de fórmulas e funções, e criação de gráficos.
Lista de exercicios algoritmos com pseudocodigoMauro Pereira
1) O documento apresenta uma lista de exercícios de algoritmos com pseudocódigo para os alunos do curso de Eletrônica Integrado sobre estruturas sequenciais, condicionais e de repetição.
2) Os exercícios incluem algoritmos para calcular área de retângulo, trocar valores de variáveis, calcular raízes de equação de 2o grau e custo de combustível.
3) Também pede algoritmos para analisar número como positivo, negativo ou zero e tipo de triângulo.
1) O documento descreve as etapas da inicialização de um sistema operacional, incluindo a execução do POST pela BIOS, a leitura do MBR pelo BIOS e o carregamento do núcleo do sistema operacional.
2) É explicado que o MBR contém informações sobre as partições do disco rígido que permitem ao BIOS carregar o código de inicialização da partição de boot.
3) As principais etapas da inicialização são a execução do POST pela BIOS, a leitura do MBR para identificar a partição de boot e o
O documento discute variáveis em programação, definindo-as como áreas da memória que armazenam dados e informações. Explica que variáveis podem ser globais ou locais e de diferentes tipos, como inteiros, reais e lógicos. Também apresenta os operadores aritméticos, relacionais e lógicos e introduz as linguagens Portugol e G-Portugol.
O documento discute o gerenciamento de arquivos e pastas no Windows e Linux. Ele explica como arquivos são salvos em pastas e como o Windows Explorer e o Konqueror (no Linux) podem ser usados para gerenciar arquivos e pastas. Também descreve as principais configurações de pastas e arquivos que podem ser ajustadas no Painel de Controle do Windows.
O documento apresenta uma introdução sobre JavaScript, explicando porque estudar a linguagem, o que pode ser feito com ela e como iniciar o estudo. É destacado que JavaScript permite adicionar comportamento interativo às páginas web e que pode ser usada para manipular conteúdo, eventos e dados.
O documento descreve as funções e ferramentas do Windows Explorer para gerenciamento de arquivos e pastas, incluindo como criar, renomear e navegar entre pastas, além de operações básicas como copiar, colar e excluir arquivos. Também menciona alguns programas que lidam com arquivos, como Bloco de Notas e Paint.
A placa-mãe conecta todos os componentes do computador, incluindo o processador, memória RAM, disco rígido e outros. Ela contém slots para expansão, conectores para periféricos e chips responsáveis por controlar a comunicação entre componentes.
Este documento discute conceitos gerais sobre sistemas de informação. Resume os principais tipos de sistemas como sistemas transacionais, sistemas de informações gerenciais e sistemas de apoio à decisão. Também define objetivos organizacionais comuns de sistemas de informação como excelência operacional, novos produtos e serviços, melhores relacionamentos com clientes e fornecedores e melhor tomada de decisões.
O documento apresenta circuitos lógicos digitais combinacionais, incluindo somadores, subtratores, decodificadores, codificadores, multiplexadores e demultiplexadores. Circuitos como meio somador, somador completo, decodificador 2x4 e multiplexador 8x1 são explicados com diagramas mostrando suas entradas e saídas. Tópicos como adição binária, subtração binária usando complemento de 2 e aplicações de multiplexadores e demultiplexadores também são brevemente descritos.
O documento descreve a história da Internet e da World Wide Web. Começa com uma introdução sobre o que é a Internet e sua abrangência atual. Em seguida, explica que a Internet surgiu da necessidade dos EUA de comunicação durante a Guerra Fria, dando origem à ARPANET. Por fim, destaca a importância fundamental da Internet e da WWW para a sociedade e empresas modernas.
O documento discute sobre multiplexadores, demultiplexadores, flip-flops e contadores digitais. Multiplexadores e demultiplexadores podem ser construídos usando portas lógicas e são usados para seleção e encaminhamento de sinais. Flip-flops armazenam estados digitais e contadores seguem sequências numéricas sob clock.
O documento discute o paradigma de programação orientado a objetos. Ele define conceitos como classe, objeto, método, atributo, herança, encapsulamento e polimorfismo. O documento também fornece exemplos de como esses conceitos são implementados em linguagens orientadas a objetos como C++ e Java.
Daniel Soto Araújo é um designer gráfico formado em Design e pós-graduado em Ensino Superior. Tem experiência em design gráfico, webdesign, multimídia e identidade visual, além de ensinar design em universidades. Seu portfólio inclui ilustrações, marcas, impressos, websites, emails marketing e redes sociais, demonstrando suas habilidades em softwares de produção gráfica, web e comunicação.
Palestra - design e mercado de trabalhoDaniel Soto
Este documento discute o campo do design e o mercado de trabalho para designers. Primeiramente, define o que é design e o papel do designer. Em seguida, descreve como o design pode atuar dentro de empresas e os tipos de empresas que contratam designers. Por fim, discute como os designers autônomos podem atuar e cobrar por seus serviços.
O documento fornece dicas sobre gestão profissional, comunicação com clientes e parceiros, importância do portfólio, empreendedorismo e identificação de oportunidades, trabalho em equipe e mercado web. Reforça a necessidade de se comunicar de forma acessível com clientes e usar jargão apenas com parceiros, além de valorizar o profissional pelo seu trabalho.
Lançamento Bahia Análise & Dados - BiodiversidadeDaniel Soto
Apresentação para background. Utilizada no coquetel de lançamento da publicação Bahia Análise & Dados. Fotos dos articulistas da publicação e de autores do flickr.
Daniel apresentando: Victor Margolin e A Política do ArtificialDaniel Soto
O documento discute as ideias de Victor Margolin sobre o futuro do design. Segundo Margolin, é necessária uma reinvenção da profissão levando em conta a sustentabilidade. Ele defende que o design passe a considerar a espiritualidade como guia para o que vale a pena desenvolver, visando o bem-estar humano de forma coletiva e respeitando os limites do natural.
CEAD 2013 - Oficina 1: Ferramentas colaborativas e de comunicação WEBTony Alexander Hild
O documento apresenta ferramentas colaborativas e de comunicação na web como Google Drive, Issuu, SlideShare, Prezi, páginas do Facebook e Jabbr. Inclui instruções para criar contas e realizar atividades colaborativas nestas plataformas.
A página apresenta a estrutura de navegação de um site sobre cultura baiana, com seções sobre a academia, programação cultural, biblioteca virtual, notícias, espaço do autor e publicações dos autores baianos.
O documento discute circuitos digitais multiplexadores e demultiplexadores. Explica como um multiplexador seleciona um sinal de entrada e o transfere para a saída e como um demultiplexador recebe um sinal multiplexado e o distribui para canais de saída. Também mostra circuitos lógicos para multiplexadores e demultiplexadores de 2 e 4 canais e como eles podem ser construídos usando blocos menores.
O documento apresenta um resumo sobre design, definindo-o como a produção da cultura material na sociedade e explicando os diferentes campos do design, incluindo design gráfico, de produto, web design e design de interação. Também descreve brevemente um projeto de desenvolvimento de site para uma ONG como parte da disciplina de um curso universitário.
O documento fornece uma introdução ao OpenGL, descrevendo seu histórico desde os anos 1980, arquitetura e pipeline de renderização. Explica como o OpenGL surgiu como um padrão aberto para computação gráfica após padrões proprietários.
O documento discute o paradigma funcional de programação, apresentando conceitos como:
1) Linguagens funcionais onde variáveis não mudam de valor durante a execução;
2) Funções como valores de primeira classe que podem ser passadas como argumentos;
3) Uso de recursão para definição de funções.
Simplificação de expressões Booleanas utilizando mapas de KarnaughTony Alexander Hild
O documento descreve como simplificar expressões Booleanas utilizando mapas de Karnaugh. Ele apresenta exemplos de simplificação com 2, 3 e 4 variáveis, mostrando como extrair os termos mínimos e obter a expressão simplificada. Além disso, explica propriedades dos mapas de Karnaugh, como sobreposição e agrupamento de mintermos, enrolamento, empacotamento e uso de valores "don't care".
Este documento discute como a percepção tridimensional é formada a partir de estímulos visuais monoculares e binoculares. As informações monoculares, como perspectiva, oclusão, densidade de textura e variação da luz, fornecem pistas estáticas de profundidade que o cérebro usa para interpretar imagens 2D. Informações como sombras e atenuação atmosférica também ajudam na percepção de profundidade.
O documento descreve os circuitos sequenciais, que combinam circuitos combinacionais e elementos de memória. Os circuitos sequenciais têm saídas influenciadas pelas entradas atuais e pelo estado atual. Os elementos de memória mais básicos são latchs e flip-flops, que armazenam um bit de informação e cujo próximo estado depende das entradas e do estado atual. Contadores e registradores são exemplos de circuitos sequenciais construídos com latchs e flip-flops.
1. O documento discute os tópicos da computação gráfica, incluindo o que é computação gráfica, suas aplicações, uma breve história e dispositivos gráficos.
2. As principais aplicações da computação gráfica incluem síntese de imagem, processamento de imagem, análise de imagem e visualização computacional.
3. A história da computação gráfica evoluiu de sistemas vetoriais para sistemas raster em PCs e estações gráficas 3D, com novas tecnologias como realidade virtual
O documento descreve as características básicas dos circuitos integrados digitais, incluindo sua composição a partir de transistores, encapsulamento em chips de silício, e classificações como SSI, MSI, LSI e VLSI de acordo com a escala de integração. Também define parâmetros elétricos como níveis lógicos de entrada e saída, correntes máximas, atrasos de propagação e famílias lógicas como TTL e CMOS.
Este documento apresenta uma introdução à linguagem de programação Haskell. Aborda tópicos como tipos de dados, operadores, funções, recursividade, pattern matching, guards e listas. Haskell é uma linguagem funcional pura com variáveis imutáveis que permite raciocinar sobre programas de forma elegante e concisa.
O documento apresenta uma introdução sobre a linguagem de programação funcional Haskell. Resume os principais pontos da apresentação em três frases:
1) Haskell é uma linguagem funcional puramente funcional, polimorficamente e staticamente tipada, baseada no lambda cálculo e nomeada em homenagem ao lógico Haskell Brooks Curry.
2) A apresentação discute os benefícios de usar Haskell como rapidez no desenvolvimento de softwares robustos, suporte para programação concorrente e paralela, e aprendizado de programação funcional.
3) Por
O documento descreve uma linguagem de programação chamada Pascal. O Pascal foi criado em 1971 por Niklaus Wirth para promover o uso de código estruturado. O Pascal foi muito popular na década de 1980 e é frequentemente usado para ensinar conceitos básicos de programação. O documento explica elementos-chave do Pascal como variáveis, constantes, operadores, estruturas de decisão e repetição.
O documento apresenta um curso básico de C++, abordando tópicos como: uma breve história da linguagem C++; introdução à lógica de programação; tipos de variáveis como inteiro, float e char; e comandos básicos como entrada e saída de dados.
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”Kratos879
O documento apresenta um curso básico de C++, abordando tópicos como: uma breve história da linguagem C++; introdução à lógica de programação; tipos de variáveis como inteiro, float e char; e comandos básicos como entrada e saída de dados.
O documento apresenta um curso básico de C++, abordando breve história da linguagem, tipos de variáveis, comandos básicos, controle de fluxo e arrays unidimensionais.
Este documento apresenta uma introdução à linguagem de programação C. Ele começa explicando o processo de tradução de código fonte para código objeto e as diferenças entre compiladores e interpretadores. Em seguida, descreve brevemente a história da linguagem C e sua estrutura básica de programação. Por fim, apresenta diretivas para pré-processadores, variáveis, entrada e saída de dados e o ambiente de desenvolvimento Dev-C++.
(1) O documento introduz conceitos fundamentais de programação de computadores como algoritmos, variáveis, tipos de dados, operadores aritméticos e a estrutura básica de um algoritmo. (2) Apresenta a pseudolinguagem PORTUGOL que permite ao programador pensar no problema sem considerar o equipamento, facilitando a transposição do problema real para o universo computacional. (3) Discutem variáveis, tipos básicos como inteiro, real, caracter e lógico, e o comando de atribuição para manipular valores nas variáveis.
Este documento apresenta um roteiro sobre programação funcional. Ele discute linguagens de programação, funções matemáticas, programação funcional, vantagens e desvantagens, implementações e comandos básicos da linguagem Haskell.
Sistemas operacionais de rede exercicio de sala-shellscriptCarlos Melo
O documento apresenta 13 exercícios de shell script com diferentes níveis de complexidade, como receber parâmetros, verificar arquivos, ordenar listas e realizar operações matemáticas. Os exercícios foram propostos como forma de praticar o desenvolvimento de scripts shell.
Linguagem C e Dev-C++ Algumas Explicaçõesnataferraz
O documento explica os conceitos básicos da linguagem C, incluindo o que é C, sua sintaxe e tipos de dados. C foi criada em 1972 por Dennis Ritchie para facilitar a criação de programas extensos com menos erros utilizando programação procedural. A sintaxe de C define regras para identificadores, variáveis e tipos de dados como inteiros, reais e caracteres.
O documento discute conceitos de função e modularização em programação. Explica como dividir um programa grande em partes menores através de funções para torná-lo mais fácil de gerenciar e testar. Fornece exemplos de como escrever funções e usar variáveis locais e globais.
Este documento apresenta notas de aula sobre a linguagem C, abordando tópicos como: 1) introdução à linguagem C, sua estrutura e objetivos do curso; 2) características e aplicações da linguagem C; 3) comparação da linguagem C com outras linguagens. Exercícios sobre a linguagem C são propostos no final.
Este documento fornece um resumo da linguagem de programação Haskell em 3 frases:
1) Haskell é uma linguagem funcional criada em 1990 que suporta avaliação preguiçosa, funções recursivas, tipos de dados algébricos e list comprehensions.
2) Quicksort é mais fácil de implementar em Haskell do que em C devido às características da linguagem.
3) O documento apresenta exemplos básicos de funções e programas em Haskell como cálculo de média e contagem de números maiores que dez.
1. A linguagem C é amplamente utilizada no meio acadêmico para desenvolvimento de pesquisas científicas e como instrumento de aprendizado.
2. O documento apresenta os principais elementos da linguagem C, incluindo sintaxe, variáveis, operadores, comandos de entrada e saída e estruturas condicionais e de repetição.
3. É uma introdução completa aos fundamentos da linguagem C para iniciantes.
Este documento apresenta uma introdução à linguagem de programação C. Discute as características e popularidade da linguagem C, os arquivos usados no desenvolvimento de programas em C, e a estrutura básica de um programa em C.
Este documento fornece um resumo de um curso introdutório sobre a linguagem de programação Pascal utilizando o compilador Turbo Pascal. O documento explica a estrutura básica de um programa Pascal e apresenta um exemplo de programa, além de definir elementos importantes como palavras reservadas, identificadores e regras para criação de nomes.
O documento discute funções em programação estruturada em C++. Explica que funções são blocos de código reutilizáveis que executam tarefas específicas e podem receber e retornar dados. Detalha a sintaxe básica de funções, incluindo o tipo de retorno, nome, parâmetros e corpo. Fornece um exemplo simples de função para soma de dois números.
1. O documento apresenta um tutorial sobre o uso do software livre GNU Octave, que é uma ferramenta de cálculo numérico e científico similar ao Matlab.
2. O tutorial explica conceitos básicos como operações matemáticas, definir variáveis, formatar números, criar gráficos e definir funções.
3. O documento também fornece exemplos de código do Octave para ilustrar cada tópico abordado.
Este documento apresenta um resumo de três frases ou menos sobre o conteúdo do documento fornecido:
O documento introduz o curso de Programação Imperativa, descrevendo o conteúdo programado, como as aulas serão ministradas e avaliadas. É apresentado o que é um computador e programa, e discutidas linguagens de programação e a linguagem C que será usada no curso.
O documento introduz os Mapas de Karnaugh, uma técnica para simplificar expressões lógicas através da representação gráfica das variáveis e termos em um mapa. Os mapas organizam as combinações lógicas de variáveis em células adjacentes de acordo com o código de Gray para facilitar a identificação de termos comuns. Exemplos demonstram como construir e usar mapas de Karnaugh para expressões de 2, 3 e 4 variáveis.
O documento introduz o paradigma imperativo de programação, definindo-o como um conjunto de instruções que alteram o estado de um programa. Apresenta a história das linguagens imperativas, desde John von Neumann até exemplos atuais como C e Pascal. Explica características-chave como variáveis, atribuições, expressões e controle de fluxo para manipular o estado de um programa.
O documento descreve os princípios fundamentais da álgebra Booleana, incluindo postulados, teoremas e formas canônicas de representação de funções Booleanas.
Computação Gráfica - Transformações Geométricas no Plano e no EspaçoTony Alexander Hild
O documento discute transformações geométricas em computação gráfica, incluindo translação, escala e rotação. Explica como matrizes são usadas para representar essas transformações e como elas afetam os pontos e objetos. Também aborda conceitos como sistemas de coordenadas, câmera virtual, frustum e suas implementações em OpenGL.
Computação Gráfica - Artquitetura de Dispositivos GráficosTony Alexander Hild
Este documento descreve os principais dispositivos de entrada e saída gráficos, incluindo teclados, mouses, joysticks, tablets, digitalizadores 3D, luvas 3D, capacetes de RV, impressoras e monitores. Os dispositivos de entrada permitem a interação humana com sistemas de computação gráfica, enquanto os dispositivos de saída geram imagens e gráficos. Vários tipos de tecnologias são discutidas, como CRT, LCD, OLED, jato de tinta e laser.
O documento discute informações visuais binoculares, incluindo acomodação, convergência e disparidade retiniana. Também explica estereogramas, que usam duas imagens bidimensionais para criar a ilusão de tridimensionalidade quando vistas separadamente por cada olho.
A Computação Gráfica é definida como um conjunto de ferramentas e técnicas para converter dados para ou de um dispositivo gráfico através do computador. Surgiu em 1955 com o primeiro computador com recursos gráficos, o Whirlwind, e tem sido aplicada em diversas áreas como medicina, engenharia, astronomia e arte, gerando imagens sintéticas e processando ou analisando imagens reais.
Egito antigo resumo - aula de história.pdfsthefanydesr
O Egito Antigo foi formado a partir da mistura de diversos povos, a população era dividida em vários clãs, que se organizavam em comunidades chamadas nomos. Estes funcionavam como se fossem pequenos Estados independentes.
Por volta de 3500 a.C., os nomos se uniram formando dois reinos: o Baixo Egito, ao Norte e o Alto Egito, ao Sul. Posteriormente, em 3200 a.C., os dois reinos foram unificados por Menés, rei do alto Egito, que tornou-se o primeiro faraó, criando a primeira dinastia que deu origem ao Estado egípcio.
Começava um longo período de esplendor da civilização egípcia, também conhecida como a era dos grandes faraós.
Atividades de Inglês e Espanhol para Imprimir - AlfabetinhoMateusTavares54
Quer aprender inglês e espanhol de um jeito divertido? Aqui você encontra atividades legais para imprimir e usar. É só imprimir e começar a brincar enquanto aprende!
2. 2
A Crise do Software
● Como diminuir o tamanho e complexidade dos software
modernos?
● Como reduzir o tempo e custo desenvolvimento de
software?
● Como aumentar a confiança que os software finalizados
irão funcionar corretamente?
3. 3
Solução para a crise
● Uma abordagem para solucionar a crise de software foi projetar
novas linguagens de programação que:
– Permitissem que programas fossem escritos de forma clara,
concisa e com um alto nível de abstração;
– Suportassem componentes de software reutilizáveis;
– Encorajassem o uso de verificação formal;
– Permitissem prototipagem rápida;
– Fornecessem ferramentas poderosas para a solução de
problemas.
● Linguagens funcionais fornecem um arcabouço particularmente
elegante para abordar estas metas.
4. 4
O que é uma Linguagem Funcional?
● De uma maneira geral:
– Programação funcional é um estilo de programação
onde o método básico de programação é a aplicação
de funções em argumentos;
– Uma linguagem funcional é aquela que suporta e
encoraja o estilo funcional;
5. 5
Exemplo
● Somando inteiros de 1 a 10 em C#:
var total = 0;
for (int i = 0; i < 10; i++)
{
total += i;
}
● O método de computação é atribuição de variáveis.
6. 6
Exemplo
● Somando inteiros de 1 a 10 em Haskell:
sum [1..10]
● O método de computação é aplicação de função.
7. 7
Histórico
● 1930:
– Alonzo Church desenvolveu o
cálculo lambda (cálculo-λ):
● Uma teoria de função simples
mas poderosa.
● 1950:
– John McCarthy desenvolve a Lisp, a primeira
linguagem funcional, com algumas
influências do cálculo lambda, mas
mantendo as atribuições de variáveis.
8. 8
Histórico
● 1960:
– Peter Landin desenvolveu a linguagem ISWIM (If
you see what i mean), a primeira linguagem
funcional pura, fortemente baseada no cálculo
lambda, sem atribuições.
● 1970:
– John Backus desenvolveu FP, uma
linguagem funcional que enfatiza
funções de ordem superior e raciocínio
sobre programas.
9. 9
Histórico
● 1970:
– Robin Milner e outros criaram ML, a primeira
linguagem funcional moderna, qual introduziu
inferência de tipos e tipos polimórficos
(generics);
– ML foi concebida como uma linguagem de
script para realizar provas formais.
● 1970-1980:
– David Turner desenvolveu uma
série de linguagens funcionais
preguiçosas (lazy), culminando no
sistema Miranda.
10. 10
Histórico
● 1987:
– Um comitê internacional
de pesquisadores
iniciou o
desenvolvimento de
Haskell, uma
linguagem funcional
lazy padronizada;
– http://www.haskell.org/h
ugs/
11. 11
Histórico
● 2003:
– O comitê publica o
relatório Haskell 98,
definindo uma definição
estável da linguagem;
– http://www.haskell.org/o
nlinereport/
12. 12
Haskell - Exemplo
f [] = []
f (x:xs) = f ys ++ [x] ++ f zs
where
ys = [ a | a <- xs, a <= x ]
zs = [ b | b <- xs, b > x ]
?
13. 13
Hugs
● Implementação do Haskell 98, e é o sistema Haskell mais
utilizado;
● A natureza interativa do Hugs o torna ideal para os
propósitos de ensino e prototipagem;
● Disponível em:
http://www.haskell.org/hugs/
14. 14
Iniciando o Hugs
● Em um sistema Unix, o Hugs pode ser iniciado a partir do
prompt de comando simplesmente escrevendo-se:
# hugs
__ __ __ __ ____ ___ _________________________________________
|| || || || || || ||__ Hugs 98: Based on the Haskell 98 standard
||___|| ||__|| ||__|| __|| Copyright (c) 1994-2005
||---|| ___|| World Wide Web: http://haskell.org/hugs
|| || Bugs: http://hackage.haskell.org/trac/hugs
|| || Version: September 2006 _________________________________________
Haskell 98 mode: Restart with command line option -98 to enable extensions
Type :? for help
Hugs>
15. 15
Iniciando o Hugs (2)
● Hugs> significa que o sistema Hugs está pronto para avaliar uma
expressão;
● Por exemplo:
Hugs> 2+3*4
14
Hugs> (2+3)*4
20
Hugs> sqrt (3^2 + 4^2)
5.0
16. 16
O Prelude padrão
● Haskell contém uma biblioteca chamada Prelude.hs que
contém um grande número de funções:
– Funções numéricas: +, *;
– Funções em listas.
17. 17
Funções em listas
● Seleciona o primeiro elemento de uma lista:
> head [1,2,3,4,5]
1
● Remove o primeiro elemento de uma lista:
> tail [1,2,3,4,5]
[2,3,4,5]
● Seleciona o enésimo elemento de uma lista:
> [1,2,3,4,5] !! 2
3
● Seleciona os primeiros n elementos de uma lista:
> take 3 [1,2,3,4,5]
[1,2,3]
18. 18
Funções em listas (2)
● Remove os primeiros n elementos de uma lista:
> drop 3 [1,2,3,4,5]
[4,5]
● Calcula o comprimento de uma lista:
> length [1,2,3,4,5]
5
● Calcula a soma dos elementos de uma lista:
> sum [1,2,3,4,5]
15
19. 19
Funções em listas (3)
● Calcula o produto dos elementos de uma lista:
> product [1,2,3,4,5]
120
● Junta duas listas:
> [1,2,3] ++ [4,5]
[1,2,3,4,5]
● Reverte uma lista:
> reverse [1,2,3,4,5]
[5,4,3,2,1]
20. 20
Aplicação de funções
● Na matemática, a aplicação de uma função é denotada
usando parêntesis, e a multiplicação é geralmente
denotada usando justaposição ou espaço.
– f(a,b) + c d
Aplica a função f à a e b, e adiciona o resultado
Aplica a função f à a e b, e adiciona o resultado
o produto ao produto de c e d.
o produto ao produto de c e d.
21. 21
Aplicação de funções (2)
● Em Haskell, a aplicação de funções é denotada usando
espaço, e a multiplicação é denotada usando *:
– f a b + c*d
Como no exemplo anterior, só que agora na
Como no exemplo anterior, só que agora na
sintaxe Haskell
sintaxe Haskell
22. 22
Aplicação de funções (2)
● Também, a aplicação de funções tem precedência sobre
todos os outros operadores:
– f a + b
Significa Significa ((ff aa)) ++ bb,, aaoo ccoonnttrráárriioo ddee ff ((aa ++ bb))
23. 23
Aplicação de funções (Exemplos)
Matemática Haskell
f(x) f x
f(x,y) f x y
f(g(x)) f (g x)
f(x,g(y)) f x (g y)
f(x)g(y) f x * g y
24. 24
Scripts em Haskell
● Apesar de haver funções na biblioteca padrão (prelude), é
possível definir funções próprias;
● Novas funções são definidas em um script, um arquivo de
texto contendo uma sequência de definições;
● Por convenção, scripts Haskell possuem extensão .hs.
25. 25
Meu primeiro script
● É útil manter duas janelas abertas ao programar em
Haskell. Uma para o script o outra para o Hugs;
● Abra um editor, digite as duas expressões e salve com o
nome teste.hs:
double x = x + x
quadruple x = double (double x)
26. 26
Meu primeiro script (2)
● Deixe o editor aberto e inicie o Hugs com:
> hugs teste.hs
ou
> hugs
> :load teste.hs
27. 27
Meu primeiro script (3)
● Agora Prelude.hs e teste.hs estão carregados, e as
funções dos dois scripts podem ser usadas:
> quadruple 10
40
> take (double 2) [1,2,3,4,5,6]
[1,2,3,4]
28. 28
Meu primeiro script (4)
● Mantendo o Hugs aberto, retorne ao editor, adicione as
definições abaixo, salve e digite :reload no Hugs:
factorial n = product [1..n]
average ns = sum ns `div` length ns
● Nota:
–
● div é cercado por aspas invertidas (crase);
● x `f` y é apenas um syntactic sugar para f x y.
● div é cercado por aspas invertidas (crase);
● x `f` y é apenas um syntactic sugar para f x y.
29. 29
Meu primeiro script (5)
> factorial 10
3628800
> average [1,2,3,4,5]
[1,2,3]
30. 30
Requisitos para nomes
● Nomes de funções e argumentos devem iniciar em caixa
baixa:
myFun fun1 arg_2 x'
● Por convensão, argumentos de lista geralmente possuem
o sufixo s nos seus nomes (notação húngara):
xs ns nss
31. 31
A regra do layout
a = 10
b = 20
c = 30
a = 10
b = 20
c = 30
a = 10
b = 20
c = 30
32. 32
A regra do layout (2)
a = b + c
where
b = 1
C = 2
d = a * 2
a = b + c
where
{b = 1
c = 2}
d = a * 2
Mesmo que
AAggrruuppaammeenntoto i mimpplílcícitioto AAggrruuppaammeenntoto e exxpplílcícitioto
33. 33
Exercícios
● 1. Teste os slides 17-19 e 25-29 usando Hugs;
● 2. Corrija os erros do programa abaixo, e teste sua
solução usando Hugs.
N = a 'div' lenght xs
where
a = 10
xs = [1,2,3,4,5]
34. 34
Exercícios
3.Tente reescrever a função last, que seleciona o último
elemento de uma lista, usando as funções vistas
anteriormente;
4.Você consegue pensar em outra solução?
3.Similarmente, reescreva a função init, que remove o último
elemento de uma lista.
35. 35
O que é um tipo?
Um tipo é um nome para uma coleção de valores
relacionados. Por exemplo, o tipo básico
Bool
contém dois valores lógicos:
False True
36. 36
Erros de tipo
● Aplicar um função à um ou mais argumentos do tipo
errado é chamado erro de tipo.
> 1 + False
Error
1 é um número e False é um valor lógico, mas
1 é um número e False é um valor lógico, mas
+ requer dois números
+ requer dois números
37. 37
Tipos em Haskell
● Se ao avaliar uma expressão e produzir um valor do tipo t,
então e tem o tipo t, escrito:
e :: t
● Toda expressão bem formada tem um tipo, que pode ser
automaticamente calculado em tempo de compilação
usando um processo chamado inferência de tipo.
38. 38
Tipos em Haskell (2)
● Todos os erros de tipo são verificados em tempo de
compilação, o que torna os programas seguros e
rápidos, removendo a necessidade de checagem de tipo
em tempo de execução;
● No Hugs, o comando :type calcula o tipo de uma
expressão, sem avaliá-la.
> not False
True
> :type not False
not False :: Bool
39. 39
Tipos básicos em Haskell
Bool Valores lógicos
Char Caracteres únicos
String String (fio) de caracteres
Int Inteiros de precisão fixa
Integer Inteiros de precisão arbitrária
Float Número de ponto flutuante
40. 40
Tipos Lista
● Uma lista é uma sequência de valores do mesmo tipo:
[False,True,False] :: [Bool]
['a','b','c','d'] :: [Char]
● De maneria geral:
[t] é o tipo de listas de elementos do tipo t.
41. 41
Tipos Lista (2)
● Nota:
– O tipo das listas não diz nada sobre o seu tamanho
[False,True] :: [Bool]
[False,True,False] :: [Bool]
– O tipo dos elementos não tem restrições. Por exemplo,
é possível criar listas de listas:
[['a'],['b','c']] :: [[Char]]
42. 42
Tipos Tupla
● Uma tupla é uma sequência de valores de tipos
diferentes:
(False,True) :: (Bool,Bool)
(False,'a',True) :: (Bool,Char,Bool)
● De modo geral:
– (t1,t2,...,tn) é o tipo de n-tuplas quais os iésimos
componentes têm o tipo ti para qualquer i em 1..n.
43. 43
Tipos Tupla (2)
● Nota:
– O tipo de uma tupla codifica seu tamanho:
(False,True) :: (Bool,Bool)
(False,True,False) :: (Bool,Bool,Bool)
– Não há restrições para o tipo dos componentes:
('a',(False,'b')) :: (Char,(Bool,Char))
(True,['a','b']) :: (Bool,[Char])
44. 44
Tipos Função
● Uma função é um mapeamento de valores de um tipo
para valores de outro tipo:
not :: Bool → Bool
isDigit :: Char → Bool
● De maneira geral:
– t1 → t2 é o tipo das funções que mapeia valores do tipo
t1 para valores do tipo t2.
45. 45
Tipos Função (2)
● Nota:
– A flecha → é digitada no teclado como ->;
– Não há restrições para o tipo de argumento e
resultados. Por exemplo, funções com múltiplos
argumentos ou resultados são possíveis usando listas
ou tuplas.
add :: (Int,Int) → Int
add (x,y) = x + y
zeroto :: Int → [Int]
zeroto n = [0..n]
46. 46
Funções Arranjadas (Curried)
● Funções com múltiplos argumentos que retornam
funções como resultado:
add' :: Int → (Int → Int)
add' x y :: x + y
add' toma um valor inteiro x e retorna uma função
add' x. Por sua vez, esta função toma um inteiro y
add' toma um valor inteiro x e retorna uma função
add' x. Por sua vez, esta função toma um inteiro y
e retorna o resultado de x + y.
e retorna o resultado de x + y.
47. 47
Funções Arranjadas (Curried) (2)
● Nota:
– add e add' produzem o mesmo resultado final, mas add
toma seus dois argumentos ao mesmo tempo,
enquanto add' toma um de cada vez:
add :: (Int,Int) → Int
add' :: Int → (Int → Int)
● Funções que tomam um argumento por vez são
chamadas funções arranjadas ou curried, em homenagem
a Haskell Curry.
48. 48
Funções Arranjadas (Curried) (3)
● Funções com mais de dois argumentos podem ser
arranjadas retornando funções aninhadas:
mult :: Int → (Int → (Int → Int))
mult x y z = x*y*z
mult toma um inteiro x e retorna uma função mult x, que
por sua vez toma um inteiro y e retorna uma função mult
mult toma um inteiro x e retorna uma função mult x, que
por sua vez toma um inteiro y e retorna uma função mult
x y, que finalmente toma um inteiro z e retorna o
x y, que finalmente toma um inteiro z e retorna o
resultado x * y * z.
resultado x * y * z.
49. 49
Por que Currying é útil?
● Funções curried são mais flexíveis que funções em tuplas,
porque funções úteis muitas vezes podem ser construídas
aplicando parcialmente uma função curried.
● Por exemplo:
add' 1 :: Int → Int
take 5 :: [Int] → [Int]
drop 5 :: [Int] → [Int]
50. 50
Convensões de curring
● Para evitar excesso de parênteses quando usa-se funções
curried, duas convenções simples são adotadas:
– A flecha → associa à direita.
Int → Int → Int → Int
SSiiggnniiffiiccaa IInntt →→ ((IInntt →→ ((IInntt →→ IInntt))))
51. 51
Convensões de curring (2)
● Por consequência, é natural aplicar uma função
associando a esquerda.
mult x y z
SSiiggnniifficicaa ((((mmuultlt xx)) yy)) zz
● A não ser que tuplas sejam requeridas, todas as funções
em Haskell são normalmente definidas na forma curried.
52. 52
Funções Polimórficas
● Uma função é chamada polimórfica (“de muitas formas”)
se seu tipo contém uma ou mais variáveis de tipo.
length :: [a] → Int
Para qualquer tipo a, length toma uma lista
de valores do tipo a e retorna um inteiro.
Para qualquer tipo a, length toma uma lista
de valores do tipo a e retorna um inteiro.
53. 53
Funções Polimórficas (2)
● Nota:
– Variáveis de tipo podem ser instanciadas para
diferentes tipos em diferentes circunstâncias:
> length [False,True]
2
> length [1,2,3,4]
4
aa == BBooooll
aa == IInntt
– Variáveis de tipo devem começar com letras
minúsculas, e usualmente são nomeadas a, b, c, etc.
54. 54
Funções Polimórficas (3)
● Várias funções do prelude são polimórficas:
fst :: (a,b) → a
head :: [a] → a
take :: Int → [a] → [a]
zip :: [a] → [b] → [(a,b)]
id :: a → a
55. Char não é um
tipo numérico
55
Funções Polimórficas (4)
● Variáveis de tipo restrito podem ser instanciadas para
qualquer tipo que satisfaça a restrição.
> sum [1,2,3]
6
> sum [1.1,2.2,3.3]
6.6
> sum ['a','b','c']
ERROR
aa == IInntt
aa == FFllooaatt
Char não é um
tipo numérico
56. 56
Funções Polimórficas (5)
● Haskell possui várias classes de tipo, incluindo:
– Num – Tipos numéricos
– Eq – Tipos de igualdade
– Ord – Tipos de relação (ordenação)
● Por exemplo:
(+) :: Num a => a → a → a
(==) :: Eq a => a → a → Bool
(<) :: Ord a => a → a → Bool
57. 57
Dicas e Sugestões
● Ao definir uma nova função em Haskell, é útil iniciar
escrevendo seu tipo;
● Em um script, é uma boa prática definir o tipo de todas as
novas funções;
● Quando definir os tipos de funções polimórficas que
utilizam números, igualdades ou relações, tenha cuidado
em incluir as classes de restrições necessárias.
58. 58
Dicas e Sugestões
add :: Num a => a -> a -> a
add x y = x + y
59. 59
Exercícios
● Quais são os tipos dos seguintes valores?
['a','b','c']
('a','b','c')
[(False,'0'),(True,'1')]
[(False,True),('0','1')]
[tail,init,reverse]
60. 60
Exercícios
● Quais são os tipos das seguintes funções?
second xs = head (tail xs)
swap (x,y) = (y,x)
pair x y = (x,y)
double x = x*2
palindrome xs = reverse xs == xs
twice f x = f(f x)
● Verifique suas respostas usando o Hugs.
61. 61
Expressões Condicionais
● Na maioria das linguagens de programação, funções
podem ser definidas usando expressões condicionais.
abs :: Int → Int
abs n = if n >= 0 then n else -n
abs toma um inteiro n se n for não-negativo,
abs toma um inteiro n se n for não-negativo,
senão, retorna -n.
senão, retorna -n.
62. 62
Expressões Condicionais
● Expressões condicionais podem ser aninhadas:
signum :: Int → Int
signum n = if n < 0 then -1 else
● Nota:
if n == 0 then 0 else 1
– Em Haskell, expressões condicionais sempre devem
ter o desvio senão (else), que evita ambiguidades com
expressões aninhadas.
63. 63
Equações restritas (Guarded Equations)
● Com alternativa para expressões, funções também podem
ser definidas usado equações restritas:
abs n | n >= 0 = n
| otherwise = -n
Como o anterior, m Como o anterior, maass uussaannddoo gguuaarrddeedd..
64. 64
Equações restritas (Guarded Equations)
● Equações restritas podem ser usadas para simplificar a
leitura de definições que envolvem múltiplas condições:
● Nota:
signum n | n < 0 = -1
| n == 0 = 0
| otherwise = 1
– A condição otherwise é definida no prelude por
otherwise = True.
65. 65
Pattern Matching
● Muitas funções possuem uma definição mais clara
utilizando pattern matching (casamento de padrões) nos
seus argumentos:
not :: Bool → Bool
not False = True
not True = False
not mapeia False para not mapeia False para TTrruuee,, ee TTrruuee ppaarraa FFaallssee
66. 66
Pattern Matching (2)
(&&) :: Bool → Bool → Bool
True && True = True
_ && _ = False
WWiillddccaarrdd
(&&) :: Bool → Bool → Bool
True && x = True , x == True
= False , x == False
False && x = False , x == False
= False , x == True
68. 68
Pattern Matching (4)
● Padrões são casados segundo a ordem top → bottom, left
→ rigth. Por exemplo, a seguinte definição sempre retorna
False:
_ && _ = False
True && True = True
● Padrões não podem repetir variáveis. Por exemplo, a
seguinte definição causa um erro:
b && b = b
_ && _ = False
69. 69
Padrões de Listas
● Internamente, toda lista não-vazia é construída pelo uso
repetido do operador (:) chamado “cons” que adiciona
um elemento ao início da lista.
[1,2,3,4]
SSiiggnniiffiiccaa 11::((22::((33::((44::[[]]))))))
70. 70
Padrões de Listas
● Funções em listas podem ser definidas utilizando padrões
x:xs.
head :: [a] → a
head (x:_) = x
tail :: [a] → [a]
tail (_:xs) :: xs
head e tail mapeia qualquer lista não-vazia para
head e tail mapeia qualquer lista não-vazia para
seus primeiros e últimos elementos
seus primeiros e últimos elementos
71. 71
Padrões de Listas
● Nota:
– O padrão x:xs somente casa listas não-vazias:
> head []
Error
– Padrões x:xs devem ser parentesados, por que a
aplicação do padrão tem prioridade sobre (:). Por
exemplo, a seguinte definição retorna um erro:
head x:_ = x
72. 72
Padrões de Inteiros
● Como na matemática, funções em inteiros podem ser
definidas usando o padrão n+k, onde n é uma variável
inteira e k>0 é uma constante inteira.
pred :: Int → Int
pred (n+1) = n
pred mapeia qualquer inteiro
positivo para seu predecessor
pred mapeia qualquer inteiro
positivo para seu predecessor
73. 73
Padrões de Inteiros
fac :: Int → Int
fac 0 = 1
fac (n+1) = n + (fac n)
74. 74
Padrões de Inteiros
● Nota:
– Padrões n+k casam somente inteiros ≥ k.
> pred 0
Error
– Padrões n+k devem ser parentesados, porque a
aplicação tem prioridade sobre +. Por exemplo, a
seguinte definição resulta em um erro:
pred n+1 = n
75. 75
Expressões Lambda
● Funções podem ser construídas sem serem nomeadas
usado expressões lambda.
λx → x + x
uma função sem nome que
toma um número x e retorna o
uma função sem nome que
toma um número x e retorna o
resultado x+x
resultado x+x
77. 77
Expressões Lambda
● Nota:
– O símbolo λ é a letra Grega lambda, e é escrita no
teclado com ;
– Na matemática, funções sem nome são usualmente
denotadas usado o símbolo ↦, como em x ↦ x + x;
– Em Haskell, o uso do símbolo λ para funções sem
nome vem do cálculo lambda, a teoria de funções no
qual Haskell é baseado.
78. 78
Por que Lambdas são úteis?
Expressões lambda poder ser usadas para dar um
significado formal para funções definidas com currying.
Por exemplo:
significa
add x y = x + y
add = λx → (λy → x + y)
79. 79
Por que Lambdas são úteis?
Expressões lambda também são úteis ao definir funções que
retornam funções como resultado.
Por exemplo:
const :: a → b → a
const x _ = x
é mais naturalmente definido por
const :: a → (b → a )
const x = λ_ x → x
80. 80
Por que Lambdas são úteis?
Expressões lambda poder ser usadas para evitar dar nomes
a funções que são referenciadas uma vez apenas.
Por exemplo:
odds n = map f [0..n-1]
where
f x = x*2 + 1
Pode ser simplificado para
odds n = map (λx → x*2 + 1) [0..n-1]
81. 81
Seções
● Um operador escrito entre seus dois argumentos pode ser
convertido em uma função curried escrita antes de seus
dois argumentos usando parênteses.
● Por exemplo:
> 1 + 2
3
> (+) 1 2
3
82. 82
Seções
● Esta convenção ainda permite que um dos argumentos do
operador seja incluído nos parênteses.
● Por exemplo:
> (1+) 2
3
> (+2) 1
3
● Geralmente, se é ⊕ um operador, então funções na forma
(⊕), (x⊕) e (⊕y) são chamadas seções.
83. 83
Por que seções são úteis?
Funções úteis as vezes podem ser construídas de uma
maneira simples utilizando seções.
Por exemplo:
(1+) – função sucessor
(1/) – função recíproca
(*2) – função para dobrar
(/2) – função para dividir ao meio
84. 84
Exercícios
1.Considere a função safetail que tem o mesmo
comportamento da função tail, exceto por safetail mapear
lista vazia para lista vazia, sendo que tail retorna um erro
neste caso.
– Defina safetail usando:
● Uma expressão condicional;
● Uma expressão abrigada (guarded);
● Casamento de padrões.
– Dica: a função null :: [a] → Bool pode ser usada para
verificar se uma lista é vazia.
85. 85
Exercícios
2.Crie três possíveis definições para o operador lógica (||)
usando casamento de padrões;
3.Redefina a seguinte versão de (&&) usando expressões
condicionais ao invés de casamento de padrões:
True && True = True
_ && _ = False
6.Faça o mesmo para a seguinte versão:
True && b = b
False && _ = False
86. 86
Listas por Compreensão (List Comprehensions)
● Na matemática, a notação por compreensão pode ser
usada para construir novos conjuntos a partir de conjuntos
antigos.
O conjunto {1,4,9,16,25} de todos os números
x2 tal que x seja um elemento do conjunto {1...5}
O conjunto {1,4,9,16,25} de todos os números
x2 tal que x seja um elemento do conjunto {1...5}
87. 87
Listas por Compreensão (2)
● Em Haskell, um notação por compreensão similar pode
ser usada para construir novas listas a partir de listas
antigas.
[x^2 | x ← [1..5]]
A lista [1,4,9,16,25] de todos os números x^2
tal que x seja um elemento da lista [1..5]
A lista [1,4,9,16,25] de todos os números x^2
tal que x seja um elemento da lista [1..5]
88. 88
Listas por Compreensão (3)
● Nota:
– A expressão x ← [1..5] é chamada geradora, pois ela
define como gerar os valores para x;
– Compreensões podem ter várias geradoras, separadas
por vírgula. Por exemplo:
> [(x,y) | x ← [1,2,3], y ← [4,5]]
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
89. 89
Listas por Compreensão (4)
● Nota:
– Alterando a ordem das geradoras altera a ordem dos
elementos na lista final:
> [(x,y) | x ← [4,5], y ← [1,2,3]]
[(1,4),(2,4),(3,4),(1,5),(2,4),(3,5)]
– Múltiplas geradoras são como laços aninhados, sendo
as últimas geradoras são os laços mais profundos onde
os valores das variáveis se alteram com mais frequência.
90. 90
Listas por Compreensão (5)
● Por exemplo:
> [(x,y) | x ← [4,5], y ← [1,2,3]]
[(1,4),(2,4),(3,4),(1,5),(2,4),(3,5)]
x ← [1,2,3] é a última geradora, sendo assim
x ← [1,2,3] é a última geradora, sendo assim
o valor do componente x
se altera com mais frequência
o valor do componente x
se altera com mais frequência
91. 91
Geradoras Dependentes
● As últimas expressões geradoras podem depender de
variáveis introduzidas nas primeiras geradoras.
[(x,y) | x ← [1..3], y ← [x..3]]
A lista [(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)]
de todos os pares dos números (x,y)
A lista [(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)]
de todos os pares dos números (x,y)
tal que x,y sejam elementos da lista [1..3] e y >= x
tal que x,y sejam elementos da lista [1..3] e y >= x
92. 92
Geradoras Dependentes
● Usando uma expressão geradora dependente pode-se
definir uma função de biblioteca que concatena uma lista
de listas.
concat :: [[a]] → [a]
concat xss = [x | xs ← xss, x ← xs]
● Por exemplo:
concat [[1,2,3],[4,5],[6]]
[1,2,3,4,5,6]
93. 93
Guards
● Listas por compreensão podem usar “guards” para
restringir o valor produzido pelas primeiras geradoras.
[x | x ← [1..10], even x]
A lista [2,4,6,8,10]
A lista [2,4,6,8,10]
de todos os números x tal que x seja
um elemento da lista [1..10] e x seja par
de todos os números x tal que x seja
um elemento da lista [1..10] e x seja par
94. [x | x <- [1..n], n `mod` x == 0]
94
Guards
● Usando “guards” é possível definir uma função que
mapeia um número inteiro positivo para sua lista de
fatores:
factors :: Int -> [Int]
factors n =
● Por exemplo:
> factors 15
[1,3,5,15]
95. 95
Guards
● Um inteiro positivo é primo se seus únicos fatores forem 1
e ele mesmo. Sendo assim, usando factors é possível
definir uma função que decide se um número é primo:
prime :: Int → Bool
prime n = factors n == [1,n]
● Por exemplo:
> prime 15
False
> prime 7
True
96. 96
Guards
● Agora, usando “guards” é possível definir uma função que
retorna a lista de todos os primos até um dado limite:
primes ::Int → [Int]
primes n = [x | x ← [2..n], prime x]
● Por exemplo:
> primes 40
[2,3,5,7,11,13,17,19,23,29,31,37]
97. 97
A função Zip
● Uma função de biblioteca muito útil, qual mapeia duas
listas para uma lista de pares de seus elementos
correspondentes.
zip :: [a] → [b] → [(a,b)]
● Por exemplo:
> zip ['a','b','c'][1,2,3,4]
[('a',1),('b',2),('c',3)]
98. 98
A função Zip
● Usando zip é possível definir uma função que retorna uma
lista de todos os pares de elementos adjacentes de outra
lista:
pairs :: [a] → [(a,a)]
pairs xs = zip xs (tail xs)
● Por exemplo:
> pairs [1,2,3,4]
[(1,2),(2,3),(3,4)]
99. ● Usando pairs é possível definir uma função que decide se
os elementos de uma lista estão ordenados:
99
sorted :: Ord a => [a] → Bool
sorted xs =
and [x <= y | (x,y) ← pairs xs]
● Por exemplo:
> sorted [1,2,3,4]
True
> sorted [1,3,2,4]
False
100. ● Usando zip é possível definir uma função que retorna uma
lista de todas as posições de um valor em uma lista:
100
positions :: Eq a => a → [a] → [Int]
positions x xs =
[i | (x',i) ← zip xs [0..n], x == x']
where n = length xs - 1
● Por exemplo:
> positions 0 [1,0,0,1,0,1,1,0]
[1,2,4,7]
101. 101
Compreensões em String
● Uma string é uma sequência de caracteres cercadas por
aspas duplas. Internamente, no entanto, strings são
representadas como listas de caracteres.
“abc” :: String
Significa Significa [['a'a',','b'b',','c'c']'] :::: [[CChhaarr]]
102. 102
● Similarmente, compreensões em strings podem ser
usadas para definir funções em strings como, por
exemplo, uma função que conta as letras minúsculas
(caixa-baixa) em uma string:
lowers :: String → Int
lowers xs =
length [x | x ← xs, isLower x]
● Por exemplo:
> lowers “Haskell”
6
103. 103
Exercícios
1. Um tripla (x,y,z) de inteiros positivos é chamada de
pitagórica se x² + y² = z². Usando uma compreensão
em lista, defina a função
pyths :: Int → [(Int,Int,Int)]
que mapeia um inteiro n para todas as triplas com
componentes em [1..n]. Por exemplo:
> pyths 5
[(3,4,5),(4,3,5)]
104. 104
Exercícios
2. Um inteiro positivo é perfeito se for igual à soma de
todos os seus fatores, excluindo o próprio número.
Usando uma compreensão de lista, defina uma
função
perfects :: Int → [Int]
que retorne a lista de todos os números perfeitos até um
dado limite. Por exemplo:
> perfects 500
[6,28,496]
106. 106
Funções recursivas
● Como visto, muitas funções podem ser definidas em
termos de outras funções.
factorial :: Int → Int
factorial n = product [1..n]
factorial mapeia qualquer inteiro n para o produto dos
factorial mapeia qualquer inteiro n para o produto dos
inteiros entre 1 e n
inteiros entre 1 e n
107. 107
Funções recursivas (2)
● Expressões são avaliadas em um processo passo-a-passo
de aplicação de funções em seus argumentos.
● Por exemplo:
factorial 4
=
product [1..4]
=
product [1,2,3,4]
=
1*2*3*4
=
24
109. 109
Funções recursivas (4)
● Em Haskell, funções podem ser definidas em termos delas
mesmas. Tal funções são chamadas recursivas.
factorial 0 = 1
factorial (n+1) = (n+1) * factorial n
factorial mapeia 0 para 1, e qualquer outro inteiro
positivo para o produto dele mesmo com o fatorial de
factorial mapeia 0 para 1, e qualquer outro inteiro
positivo para o produto dele mesmo com o fatorial de
seu predecessor.
seu predecessor.
111. 111
Funções recursivas (nota)
● factorial 0 = 1 é apropriado pois 1 é o valor identidade da
multiplicação: 1*x = x = x*1
● A definição da função recursiva diverge em inteiros < 0
porque o caso base nunca é alcançado:
> factorial (-1)
Error: Control stack overflow
112. 112
Porque recursão é útil
● Algumas funções, como factorial, são mais simples de
definir em termos de outras funções.
● Como visto, no entanto, muitas funções podem ser
naturalmente definidas em termos delas mesmas.
● Propriedades de funções definidas usando recursão
podem ser provadas usando uma simples porém
poderosa técnica matemática de indução.
113. 113
Recursões em listas
● Recursão não se restringe à números, mas também pode
ser usado para definir funções em listas.
product :: [Int] → Int
product [] = 1
product (x:xs) = x * product xs
product mapeia a lista vazia para 1, e qualquer outra
lista não-vazia para sua cabeça multiplicada pelo
product mapeia a lista vazia para 1, e qualquer outra
lista não-vazia para sua cabeça multiplicada pelo
produto de sua calda.
produto de sua calda.
115. 115
Recursões em listas (3)
● Usando o mesmo padrão de recursão como em product
pode-se definir a função length em listas.
length :: [a] → Int
length [] = 0
length (_:xs) = 1 + length xs
length mapeia um lista vazia para 0, e qualquer outra
lista não-vazia para o sucessor do comprimento de
length mapeia um lista vazia para 0, e qualquer outra
lista não-vazia para o sucessor do comprimento de
sua calda.
sua calda.
117. 117
Recursões em listas (5)
● Usando um padrão similar de recursão pode-se definir a
função reverse em listas.
reverse :: [a] → [a]
reverse [] = []
reverse (x:xs) = reverse xs ++ [x]
reverse mapeia um lista vazia outra lista vazia, e
qualquer outra lista não-vazia para o reverso da sua
reverse mapeia um lista vazia outra lista vazia, e
qualquer outra lista não-vazia para o reverso da sua
calda concatenada com a cabeça.
calda concatenada com a cabeça.
119. 119
Múltiplos argumentos em recursão
● Funções com mais de um argumento também podem ser
definidas usando recursão.
● Por exemplo, zipping os elementos de duas listas:
zip :: [a] → [b] → [(a,b)]
zip [] _ = []
zip _ [] = []
zip (x:xs) (y:ys) = (x,y) : zip xs ys
120. 120
Múltiplos argumentos em recursão (2)
● Remover os primeiros n elementos de uma lista:
drop :: Int → [a] → [a]
drop 0 xs = xs
drop (n+1) [] = []
drop (n+1) (_:xs) = drop n xs
● Concatenar duas listas:
(++) :: [a] → [a] → [a]
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
121. 121
Quicksort
● O algoritmo quicksort para ordenar uma lista de inteiros
pode ser especificado pelas duas regras seguintes:
– Uma lista vazia já está ordenada;
– Listas não-vazias podem ser ordenadas ordenando os
valores da cauda <= à cabeça, ordenando os valores
da cauda > que a cabeça, e concatenando as duas
listas resultantes em cada lado do valor da cabeça.
122. 122
Quicksort (2)
● Usando recursão, esta especificação pode ser traduzida
diretamente para uma implementação:
qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) =
qsort menores ++ [x] ++ qsort maiores
where
menores = [a | a <- xs, a <= x]
maiores = [b | b <- xs, b > x]
Nota:
Esta é provavelmente a implementação mais
simples de quicksort em qualquer linguagem de
programação.
Nota:
Esta é provavelmente a implementação mais
simples de quicksort em qualquer linguagem de
programação.
124. 124
Exercícios
● Sem olhar no prelude padrão, defina as seguinte biblioteca de funções usando
recursão:
– Verificar se todos os valores em uma lista são verdadeiros:
and :: [Bool] → Bool
– Concatenar uma lista de listas:
concat :: [[a]] → [a]
– Produzir uma lista com n elementos idênticos:
replicate :: Int → a → [a]
– Selecionar o iésimo elemento de uma lista:
(!!) :: [a] → Int → a
– Verificar se um valor é um elemento de da lista:
elem :: Eq a => a → [a] → Bool
126. 126
Introdução
● Uma função é chamada de alta ordem se ela toma uma
função como argumento ou retorna uma função como
resultado.
twice :: (a → a) → a → a
twice f x = f (f x)
twice é uma função de alta ordem porque toma uma
twice é uma função de alta ordem porque toma uma
função como seu primeiro argumento
função como seu primeiro argumento
127. 127
Porque são tão úteis?
● Idiomas comuns de programação podem ser
codificados como funções dentro própria linguagem.
● Linguagens de domínio específico podem ser definidas
como coleções de funções de alta ordem.
● Propriedades algébricas de funções de alta ordem
podem ser usadas para raciocinar sobre programas.
128. 128
A função map
● A função de alta ordem da biblioteca chamada map aplica
uma função para cada elemento de uma lista.
map :: (a → b) → [a] → [b]
● Por exemplo:
> map (+1) [1,3,5,7]
[2,4,6,8]
129. 129
A função map (2)
● A função map pode ser definida em uma maneira
particularmente simples usando compreensão de lista.
map f xs = [f x | x ← xs]
Alternativamente, para provar, a função map pode ser
definida utilizando recursão:
map f [] = []
map f (x:xs) = f x : map f xs
130. 130
A função filter
● A função de alta ordem filter seleciona todos os
elementos de uma lista que satisfazem um predicado.
filter :: (a → Bool) → [a] → [a]
● Por exemplo:
> filter even [1..10]
[2,4,6,8,10]
131. 131
A função filter (2)
● Filter pode ser definida utilizando compreensão de lista.
filter p xs = [x | x ← xs, p x]
Alternativamente, pode ser definida utilizando recursão:
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
132. 132
A função foldr
● Várias funções em listas podem ser definidas utilizando o
seguinte padrão simples:
f [] = v
f (x:xs) = x ⊕ f xs
f mapeia um lista vazia para algum valor v, e
qualquer outra lista não vazia para alguma uma
função ⊕ aplicada na cabeça e f na calda
f mapeia um lista vazia para algum valor v, e
qualquer outra lista não vazia para alguma uma
função ⊕ aplicada na cabeça e f na calda
133. 133
A função foldr (2) - Exemplo
sum [] = 0
sum (x:xs) = x + sum xs v = 0
v = 0
⊕ = +
⊕ = +
product [] = 1
product (x:xs) = x * product xs
v = 1
⊕ = *
v = 1
⊕ = *
and [] = True
and (x:xs) = x && and xs
v = True
⊕ = &&
v = True
⊕ = &&
134. 134
A função foldr (3)
● A função de alta ordem foldr (fold right) encapsula este
padrão de recursão simples, juntamente com a função ⊕
e o valor v como argumentos.
sum = foldr (+) 0
product = foldr (*) 1
or = foldr (||) False
and = foldr (&&) True
135. 135
A função foldr (4)
● foldr pode ser definida usando recursão:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f v [] = v
foldr f v (x:xs) = f x (foldr f v xs)
● No entanto, é melhor pensar em foldr de forma não
recursiva, simultaneamente substituindo cada (:) em uma
lista para um função dada, e [] para um valor dado.
136. 136
A função foldr (5)
sum [1,2,3]
=
foldr (+) 0 [1,2,3]
=
foldr (+) 0 (1:(2:(3:[])))
=
1+(2+(3+0))
=
6
Substitua cada (:)
por (+) e [] por 0
Substitua cada (:)
por (+) e [] por 0
137. 137
A função foldr (6)
product [1,2,3]
=
foldr (*) 1 [1,2,3]
=
foldr (*) 1 (1:(2:(3:[])))
=
1*(2*(3*1))
=
6
Substitua cada (:)
por (*) e [] por 1
Substitua cada (:)
por (*) e [] por 1
138. 138
A função foldr (7)
● Mesmo foldr encapsulando um padrão de recursão
simples, ela pode ser usada para definir muitas outras
funções do que se possa esperar.
● Relembrando a função length:
length :: [a] -> Int
length [] = 0
length (_:xs) = 1 + length xs
139. Substitua cada (:)
por λ_ n → 1+n e
139
A função foldr (8)
length [1,2,3]
=
length (1:(2:(3:[])))
=
1+(1+(1+0))
=
3
Substitua cada (:)
por λ_ n → 1+n e
[] por 0
[] por 0
length = foldr (_ n -> 1+n) 0
140. Reverse [] = []
reverse (x:xs) = reverse xs ++ [x]
Substitua cada (:)
por λx xs → xs ++
140
A função foldr (9)
reverse [1,2,3]
=
reverse (1:(2:(3:[])))
=
(([] ++ [3]) ++ [2]) ++ [1]
=
[3,2,1]
Substitua cada (:)
por λx xs → xs ++
[x] e [] por []
[x] e [] por []
● Agora relembrando a função reverse:
141. Substitua cada (:)
por (:) [] por ys
141
A função foldr (10)
● Portanto, nós temos:
(++ ys) = foldr (:) ys Substitua cada (:)
por (:) [] por ys
reverse =
foldr (x xs -> xs ++ [x]) []
● Finalmente, nota-se que a função de concatenação (++)
tem uma definição particularmente compacta utilizando
foldr:
142. 142
Por que foldr é útil?
● Algumas funções recursivas em listas, como sum, são
mais simples de definir usando foldr;
● Propriedades de funções definidas usando foldr podem
ser provadas usando propriedades algébricas de foldr,
como fusão e a regra da banana split;
● Otimizações avançadas de programa podem ser simples
se foldr é usado ao invés de recursão explícita.
143. (.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = x -> f (g x)
143
Outras funções de biblioteca
● A função de biblioteca (.) retorna a composição de duas
funções como um única função.
● Por exemplo:
odd :: Int -> Bool
odd = not . even
144. 144
Outras funções de biblioteca (2)
● A função de biblioteca all decide se todos os elementos de
uma lista satisfazem um dado predicado.
all :: (a -> Bool) -> [a] -> Bool
all p xs = and [p x | x <- xs]
● Por exemplo:
> all even [2,4,6,8,10]
True
145. 145
Outras funções de biblioteca (3)
● Similarmente, a função de biblioteca any decide se pelo
menos um elemento de uma lista satisfaz um dado
predicado.
any :: (a -> Bool) -> [a] -> Bool
any p xs = or [p x | x <- xs]
● Por exemplo:
> any isSpace "abc def"
True
146. takeWhile :: (a -> Bool) -> [a] -> [a]
takeWhile p [] = []
takeWhile p (x:xs)
146
Outras funções de biblioteca (4)
● A função de biblioteca takeWhile seleciona elementos de
uma lista enquanto um predicado for verdadeiro.
| p x = x : takeWhile p xs
| otherwise = []
● Por exemplo:
> takeWhile isAlpha "abc def"
"abc"
147. dropWhile :: (a -> Bool) -> [a] -> [a]
dropWhile p [] = []
dropWhile p (x:xs)
147
Outras funções de biblioteca (5)
● A função de biblioteca takeWhile seleciona elementos de
uma lista enquanto um predicado for verdadeiro.
| p x = dropWhile p xs
| otherwise = x:xs
● Por exemplo:
> dropWhile isSpace " abc"
"abc"
148. 148
Exercícios
● Expresse a compreensão [f x | x ← xs, p x] utilizando as
funções map e filter.
● Redefina map f e filter p usando foldr.
150. 150
O que é um analisador (parser)?
● Um analisador é um programa que analisa um trecho de
texto para determinar sua estrutura sintática.
2*3+4 significa
+
* 4
2 3
151. 151
Para que são utilizados?
● Praticamente todos programas do cotidiano usam alguma
forma análise para pré-processar suas entradas:
Hugs
Unix
Browser
analisa
Programas Haskell
Scripts de shell
Documentos HTML
152. 152
O tipo Parser
● Em uma linguagem funcional como Haskell, analisadores
podem ser vistos naturalmente como funções:
type Parser = String -> Tree
Um analisador é uma função que toma uma string e
Um analisador é uma função que toma uma string e
retorna alguma forma de árvore
retorna alguma forma de árvore
153. 153
O tipo Parser (2)
● No entanto, um analisador pode não requerer toda sua
string de entrada, sendo assim também é retornada a
entrada não utilizada.
type Parser = String -> (Tree,String)
● Uma string pode ser analisada de várias maneiras,
incluindo nenhuma, então generaliza-se para uma lista de
resultados:
type Parser = String -> [(Tree,String)]
154. 154
O tipo Parser (3)
● Finalmente, um analisador nem sempre pode produzir
uma árvore, então generaliza-se para uma valor de
qualquer tipo:
type Parser = String -> [(a,String)]
Nota:
Para simplificar, esta sendo considerado somente
analisadores que ou falham e retornam um lista vazia
de resultados, ou têm sucesso e retornam uma lista
singleton (apenas um valor).
Nota:
Para simplificar, esta sendo considerado somente
analisadores que ou falham e retornam um lista vazia
de resultados, ou têm sucesso e retornam uma lista
singleton (apenas um valor).
155. 155
Analisadores básicos
● O analisador item falha se a entrada é vazia, e consome o
primeiro caractere caso contrário:
item :: Parser Char
item = inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)]
156. 156
Analisadores básicos (2)
● O analisador failure sempre falha:
failure :: Parser a
failure = inp -> []
● O analisador return sempre tem sucesso, retornando o
valor v sem consumir nenhuma entrada:
return :: a -> Parser a
return v = inp -> [(v,inp)]
157. 157
Analisadores básicos (2)
● O analisador p +++ q se comporta como o analisador p se
tiver sucesso, e como o analisador q caso contrário:
(+++) :: Parser a -> Parser a -> Parser a
p +++ q = inp -> case p inp of
[] -> parse q inp
[(v,out)] -> [(v,out)]
● A função parse aplica um analisador a uma string:
parse :: Parser a -> String -> [(a,String)]
parse p inp = p inp
158. 158
Exemplos
● O comportamento dos cinco analisadores primitivos
podem ser ilustrados com exemplos simples:
% hugs parse.hs
> parse item “”
[]
> parse item “abc”
[('a',”bc”)]
160. 160
Nota
● O arquivo de biblioteca Parsing está disponível na web na
home page de Programming in Haskell.
● O tipo Parser é um monad, uma estrutura matemática que
ser provou útil na modelagem de vários tipos de
computações diferentes.
161. 161
Sequenciamento
● Uma sequência de analisadores pode ser combinada um
um único analisador composto utilizando a palavra-chave
do.
● Por exemplo:
p :: Parser (Char, Char)
p = do x <- item
item
y <- item
return (x,y)
162. 162
Sequenciamento (2)
● Se qualquer analisador em uma sequência de
analisadores falhar, então a sequência interia falhará. Por
exemplo:
> parse p "abcdef"
[(('a','c'), "def")]
> parse p "ab"
[]
● A notação do não é especificada no tipo Parser, mas pode
ser utilizada com qualquer tipo monadico.
163. 163
Primitivas derivadas
● Analisando um caractere que satisfaz um predicado:
sat :: (Char -> Bool) -> Parser Char
sat p = do x <- item
if p x then
return x
else
failure
164. 164
Primitivas derivadas (2)
● Analisando um dígito e caracteres específicos:
digit :: Parser Char
digit = sat isDigit
char :: Char -> Parser Char
char x = sat (x ==)
● Aplicando um analisador zero ou mais vezes:
many :: Parser a -> Parser [a]
many p = many1 p +++ return []
165. 165
Primitivas derivadas (3)
● Aplicando um analisador uma ou mais vezes:
many1 :: Parser a -> Parser []
many1 p = do v <- p
vs <- many p
return (v:vs)
● Analisando um string de caracteres específica:
string :: String -> Parser String
string [] = return []
string (x:xs) = do char x
string xs
return (x:xs)
166. 166
Exemplo
● Agora é possível definir um analisador que consome um
lista de um ou mais dígitos de uma string:
p :: Parser String
p = do char '['
d <- digit
ds <- many (do char ','
digit)
char ']'
return (d:ds)
167. 167
Exemplo (2)
● Agora é possível definir um analisador que consome um
lista de um ou mais dígitos de uma string:
> parse p "[1,2,3,4]"
[("1234","")]
> parse p "[1,2,3,4"
[]
Nota:
Bibliotecas de análise mais sofisticadas podem
indicar e/ou recuperar-se de erros na string de
entrada.
Nota:
Bibliotecas de análise mais sofisticadas podem
indicar e/ou recuperar-se de erros na string de
entrada.
168. 168
Expressões aritméticas
● Considerando uma simples forma de expressões
construídas a partir de dígitos únicos usando operações
de adição + e multiplicação *, juntas com parênteses.
● Assumindo também que:
– * e + associados a direita;
– * tem prioridade maior do que +.
169. 169
Expressões aritméticas (2)
● Formalmente, a sintaxe de tais expressões é definida pela
seguinte gramática livre de contexto:
exp → term '+' expr | term
term → factor '*' term | factor
factor → digit | '(' expr ')'
digit → '0' | '1' | … | '9'
170. 170
Expressões aritméticas (2)
● No entanto, por razões de eficiência, é importante fatorizar
as regras para expr e term.
exp → term ('+' expr | ε)
term → term ('*' term | ε)
Nota:
O símbolo ε denota uma string vazia.
Nota:
O símbolo ε denota uma string vazia.
171. 171
Expressões aritméticas (2)
● Agora é fácil traduzir a gramática em um analisador que
avalia expressões, simplesmente reescrevendo as regras
da gramática utilizando as primitivas de análise.
expr :: Parser Int
expr = do t <- term
do char '+'
e <- expr
return (t + e)
+++ return t
172. 172
Expressões aritméticas (3)
term :: Parser Int
term = do f <- factor
do char '*'
t <- term
return (f * t)
+++ return f
factor :: Parser Int
factor = do d <- digit
return (digitToInt d)
+++ do char '('
e <- expr
char ')'
return e
175. 175
Introdução
● Até agora vimos como Haskell pode ser usado para
escrever programas em lote que tomam todas as suas
entradas no início e retornam todas as suas saídas no
final.
programa
em lote
programa
em lote
entradas saídas
176. 176
teclado
programa
interativo
entradas saídas
tela
Introdução (2)
● No entanto, também gostaríamos de usar Haskell para
escrever programas interativos que leem a partir de um
teclado e escrevem na tela, enquanto estiverem em
execução.
177. 177
O problema
● Programas em Haskell são funções matemáticas puras:
– Programas em Haskell não têm efeitos colaterais.
● No entanto, ler de um teclado e escrever em uma tela são
efeitos colaterais:
– Programas interativos tem efeitos colaterais.
178. 178
A solução
● Programas interativos podem ser escritos em Haskell
usando tipos para distinguir expressões puras de ações
impuras que podem envolver efeitos colaterais.
IIOO aa
Os tipos de ações que
retornam um valor do tipo a.
Os tipos de ações que
retornam um valor do tipo a.
179. 179
Por exemplo
IIOO CChhaarr
IIOO (())
O tipo de ações que
retornam um caractere.
O tipo de ações que
retornam um caractere.
O tipo de ações puramente
com efeitos colaterais que
não retornam nenhum
O tipo de ações puramente
com efeitos colaterais que
não retornam nenhum
valor.
valor.
Nota:
() é um tipo de tupla sem componentes.
Nota:
() é um tipo de tupla sem componentes.
180. – A ação getChar lê um caractere do teclado, ecoa na
tela, e retorna o caractere como seu valor de resultado.
180
Ações básicas
● A biblioteca padrão fornece várias ações incluindo as
seguintes ações primitivas:
getChar :: IO Char
181. 181
Ações básicas (2)
● A ação putChar c escreve o caractere c na tela, e não
retorna nenhum valor como resultado:
putChar :: Char -> IO ()
● A ação return v simplesmente retorna o valor v, sem
realizar nenhuma interação:
return :: a -> IO a
182. 182
Sequenciamento
● Uma sequência de ações podem ser combinadas como
uma única ação composta usando a palavra do.
a :: IO (Char,Char)
a = do x <- getChar
getChar
Y <- getChar
return (x,y)
● Por exemplo:
183. 183
getLine :: IO String
getLine = do x <- getChar
if x == 'n' then
return []
else
do xs <- getLine
return (x:xs)
Primitivas derivadas
● Lendo uma string a partir do teclado:
184. 184
putStr :: String -> IO ()
putStr [] = return ()
putStr (x:xs) = do putChar x
putStr xs
putStrLn :: String -> IO ()
putStrLn xs = do putStr xs
putChar 'n'
Primitivas derivadas(2)
● Escrevendo uma string na tela:
● Escrevendo uma string e movendo para uma nova linha:
185. 185
strlen :: IO ()
strlen = do putStr "Enter a string: "
Xs <- getLine
putStr "The string has "
putStr (show (length xs))
putStrLn " characters"
Exemplo
● Agora é possível definir uma ação que espera uma string
ser entrada e mostra seu comprimento:
186. 186
Exemplo (2)
> strlen
Enter a string: abcde
The string has 5 characters
Nota:
Avaliar uma ação executa seus efeitos colaterais,
com seu valor final de resultado sendo descartado.
Nota:
Avaliar uma ação executa seus efeitos colaterais,
com seu valor final de resultado sendo descartado.
187. 187
Jogo da forca
● Considere a seguinte versão do jogo da forca:
– Um jogador digita uma palavra secretamente;
– O outro jogador tenta deduzir a palavra, entrando uma
sequência de “chutes”;
– Para cada “chute”, o computador indica quais letras da
palavra secreta ocorrem no “chute”;
– O jogo acaba quando o “chute” estiver correto.
188. 188
Jogo da forca (2)
● Foi adotado a abordagem top-down para implementar o
jogo da forca em Haskell, iniciando como se segue:
hangman :: IO ()
hangman =
do putStrLn "Think of a word: "
Word <- sgetLine
putStrLn "Try to guess it:"
guess word
189. 189
sgetLine :: IO String
sgetLine = do x <- getCh
if x == 'n' then
do putChar x
return []
else
do putChar '-'
Xs <- sgetLine
return (x:xs)
Jogo da forca (3)
● A ação sgetLine lê um linha de texto do teclado, ecoando
cada caractere como um traço -:
190. 190
import System.IO
getCh :: IO Char
getCh = do hSetEcho stdin False
C <- getChar
hSetEcho stdin True
return c
Jogo da forca (4)
● A ação getCh lê um único caractere do teclado, sem ecoar
para a tela:
191. 191
guess :: String -> IO ()
guess word =
do putStr "> "
Xs <- getLine
if xs == word then
putStrLn "You got it!"
else
do putStrLn (diff word xs)
guess word
Jogo da forca (5)
● A função guess é o loop principal, que requisita e
processa os “chutes” até o jogo terminar:
192. Jogo da forca (6)
● A função diff indica quais caracteres de uma string
ocorrem na segunda string:
[if elem x ys then x else '-' | x <- xs]
192
diff :: String -> String -> String
diff xs ys =
● Por exemplo:
> diff "haskell" "pascal"
"-as--ll"
193. Dica:
Represente o tabuleiro como
uma lista de cinco inteiros que
representam o número de
asteriscos remanescentes em
cada linha. Por exemplo, o
tabuleiro inicial é: [5,4,3,2,1].
193
1: * * * * *
2: * * * *
3: * * *
4: * *
5: *
Exercício
● Implemente o jogo nim em Haskell
– Regras:
● O tabuleiro é composto de 5 linhas
de asteriscos;
● Dois jogadores revesam a
remoção de um ou mais asteriscos
do fim de uma única linha;
● O ganhador é o jogador que
remover o último asterisco ou
asteriscos do tabuleiro. Dica:
Represente o tabuleiro como
uma lista de cinco inteiros que
representam o número de
asteriscos remanescentes em
cada linha. Por exemplo, o
tabuleiro inicial é: [5,4,3,2,1].
195. Declarações de tipo
● Em Haskell, um novo nome para um tipo existente pode
ser definido usando uma declaração de tipo.
type String = [Char]
String String éé uumm ssiinnôônniimmoo ddee ttiippoo [[CChhaarr]]..
196. Declarações de tipo (2)
● Declarações de tipo podem ser usadas para tornar outros
tipos mais simples de ler. Por exemplo, dado
type Pos = (Int,Int)
● Pode-se definir:
origin :: Pos
origin = (0,0)
left :: Pos -> Pos
left (x,y) = (x-1,y)
197. Declarações de tipo (3)
● Como definições de funções, declarações de tipo também
podem conter parâmetros. Por exemplo, dado
type Pair a = (a,a)
● Pode-se definir:
mult :: Pair Int -> Int
mult (m,n) = m*n
copy :: a -> Pair a
copy x = (x,x)
198. Declarações de tipo (3)
● Declarações de tipo podem ser aninhadas:
type Pos = (Int,Int)
type Trans = Pos ->
Pos
● No entando, não podem ser recursivas:
type Tree = (Int,[Tree])
199. 199
Declarações de dados
● Um tipo completamente novo pode ser definido
especificando seus valores uma uma declaração de
dados.
data Bool = False | True
Bool é um novo tipo, com dois
novos valores False e True.
Bool é um novo tipo, com dois
novos valores False e True.
200. Declarações de dados (2)
● Nota:
– Os dois valores False e True podem ser chamados de
construtores do tipo Bool;
– Nomes de tipos e construtores devem iniciar com letra
maiúscula;
– Declarações de dados são similares à gramáticas livres
de contexto. O primeiro especifica os valores do tipo, e
o último as sentenças da linguagem.
201. Declarações de dados (3)
● Valores de novos tipos podem ser usados da mesma
forma dos tipos nativos. Por exemplo, dado
data Answer = Yes | No | Unknown
● Pode-se definir:
answers :: [Answer]
answers = [Yes,No,Unknown]
flip :: Answer -> Answer
flip Yes = No
flip No = Yes
flip Unknown = Unknown
202. Declarações de dados (4)
● Os construtores um uma declaração de dados também
podem possuir parâmetros. Por exemplo, dado
data Shape = Circle Float
● Pode-se definir:
| Rect Float Float
square :: Float -> Shape
square n = Rect n n
area :: Shape -> Float
area (Circle r) = pi * r^2
area (Rect x y) = x * y
203. Declarações de dados (5)
● Nota:
– Shape possui valores da forma Circle r onde r é float, e
Rect x y onde x e y são floats.
– Circle e Rect podem ser vistos como funções que
constroem valores do tipo Shape:
Circle :: Float -> Shape
Rect :: Float -> Float -> Shape
204. Declarações de dados (6)
● Sem surpresas, as próprias declarações de dados podem
conter parâmetros. Por exemplo, dado
data Maybe a = Nothing | Just a
● Pode-se definir:
safediv :: Int -> Int -> Maybe Int
safediv _ 0 = Nothing
safediv m n = Just (m `div` n)
safehead :: [a] -> Maybe a
safehead [] = Nothing
safehead xs = Just (head xs)