\n'; document.write(barra); } } changePage();
O capítulo 1 introduziu os fundamentos da programação funcional em Haskell. Vamos agora usar o sistema Hugs para alguma programação prática, e o principal propósito deste capítulo é dar uma introdução ao Hugs.
Iniciando o programa, vamos aprender os módulos básicos do Haskell, nos quais os programas podem ser escritos em múltipls arquivos interdependentes, e que podem usar as funções "embutidas" nas bibliotecas de prelúdio.
Começaremos o capítulo tomano um primeiro programa Haskell ou script, que consiste de exemplos numéricos do Capítulo 1. Como foi definido, um script pode conter comentários.
|
{-###################################################### FirstScript.hs Simon Thompson, Junho 1998 O propósito desse script é: - ilustrar alguns exemplos com inteiros (Int) - mostrar o primeiro exemplo de um script ########################################################-} -- O valor de size é um inteiro (Int), definido como a -- soma de doze e treze size :: Int size = 12+13
-- a função para o quadrado de um inteiro square :: Int -> Int square n = n*n
-- A função para o dobro de um inteiro double :: Int -> Int double n = 2*n
-- Um exemplo usando double, square e size example :: Int example = double (size - square (2+2)) |
Figura 2.1. Um exemplo de um script tradicional
Clique aqui para baixar o código fonte de FirstScript.hs
Um comentário em um script é uma peça chave de informação para uma pessoa que estuda o código. Ele pode conter uma explanação informal aobre como uma função trabalha, como ele pode ou não pode ser usada, assim por diante.
Existem dois estilos diferentes de scripts em Haskell, que refletem duas diferentes filosofias de programação.
Tradicionalmente, todo código do programa é interpretado com o texto do programa, exceto onde é explicitamente indicado que é comentário. Este é o estilo de FirstScript.hs, na Figura 2.1. Scripts deste estilo são armazenados em arquivos com a extensão '.hs'.
Comentários são indicados de duas formas. O símbolo '--' começa um comentário que que ocupará o restante da linha à direita do símbolo. Comentários também podem ser delimitados pelos símbolos '{-' e '-}'. Estes comentários podem ser de tamanho arbitrário, podendo ser de mais de uma linha, bem como englobando outros comentários; então eles são chamados de nested comments.
|
###################################################### FirstScript.hs Simon Thompson, Junho 1998 O propósito desse script é: - ilustrar alguns exemplos com inteiros (Int) - mostrar o primeiro exemplo de um script ######################################################## O valor de size é um inteiro (Int), definido como a soma de doze e treze > size :: Int > size = 12+13
a função para o quadrado de um inteiro > square :: Int -> Int > square n = n*n
A função para o dobro de um inteiro > double :: Int -> Int > double n = 2*n
Um exemplo usando double, square e size > example :: Int > example = double (size - square (2+2)) |
Figura 2.2. Um exemplo de um literate script
Clique aqui para baixar o código fonte de FirstScript.lhs
A alternativa, o literate considera que qualquer coisa escrita é um comentário do programa, e o Código do programa precisa ser sinalizado explicitamente da mesma forma. Uma versão literate do script está na Figura 2.2, onde ele pode ser visto em uma linha começando com '>', e é separado do resto do texto por linhas em branco. Literate scrips são armazenados em arquivos de extensão '.lhs'.
As duas formas enfatizam diferentes aspectos da programação. A tradicional preferência para o programa, enquanto o literate enfatiza que existe mais programação que simplesmente criar definições. Projetar decisões precisa ser explicado, condições para o uso de funções a assim por diante precis ser escrito e detalhado - isto é benéfico para ambos, o usuário e o programador e de fatopara nós mesmos se formos olhar para um código escrito no passado, e precisarmos modificá-lo e entendê-lo.
Hugs é uma implementação de Haskell que roda em PCs (sob Windows 9x/NT/2000) e sistemas Unix, incluindo Linux e recentemente em Mac (Mac OS X). Ele é livremente distribuído na Home Page do Haskell
Embora disponível em diversas plataformas, os programas apresentam melhor desempenho na plataforma Unix. Vale lembrar que o Hugs é um interpretador. O compilador Haskell mais usado é o ghc. Mas ainda existe muita pesquisa na área para criar um compilador mais eficiente. Hoje a maioria da equipe que criou o Haskell trabalha para a Microsoft e ajudam a desenvolver a .NET.
Para iniciar o Hugs o Unix, digite hugs do prompt; para executar Hugs usando um arquivo particular, digite Hugs seguido do nome do arquivo em questão, como em
hugs FirstLiterateEm sistemas Windows, Hugs é executado a partir do Menu Iniciar no local designado na hora da instalação; para executar Hugs para um arquivo particular, dê um clique duplo no ícone do arquivo em questão.
Scripts Haskell trazem a extensão .hs ou .lhs (para literate scripts); somente esses arquivos podem ser carregados, e suas extensões podem ser omitidas quando Hugs é chamado ou pelo comando :load command dentro do Hugs.
![]() |
Figura 2.3. Uma sessão Hugs no Windows
Como foi dito anteriormente, o interpretador Hugs avalia expressões digitadas no prompt. Entre no Hugs e carregue o programa de uma das formas expostas. Podemos testar no Hugs a avaliação de size, bem como dois exemplos mais complexos:
Como pode ser visto no exemplo, nós podemos avaliar expressões que usam as definições no script atual. Neste caso, ele é o FirstLiterate.lhs (ou FirstLiterate.hs).
Uma das vantagens da interface do Hugs é que é fácil experimentar as funções, tentando avaliações diferentes simplesmente digitando as expressões no teclado. Se quisermos avaliar uma expressão complexa, ela pode ser fácil adiconar ao programa, como na definição
Feito isso, precisamos apenas digitar test no prompt Main>
Comandos hugs começam com dois pontos, ':'. Um resumo dos principais comandos seguem abaixo.
| :load arquivo | Carrega o arquivo Haskell arquivo.hs ou arquivo.lhs. A extensão .hs ou .lhs não precisa ser incluída no nome do arquivo. |
| :reload | Repete o último comando load. |
| :edit first.lhs | Edita o arquivo first.lhs no editor de textos default. Note que a extensão é necessária nesse caso. Veja a seção seguinte para mais informações sobre edição. |
| :type exp | Retorna o tipo da expressão exp. Por exemplo, o resultado de digitar :type size+2 é Int. |
| :info name | Retorna informações sobre name. |
| :find name | Abre o editor de textos no arquivo contendo a definição de name. |
| :quit | Sai do sistema. |
| :? | Retorna uma lista dos comandos Hugs. |
| !com | Executa o comando Unix ou DOS com. |
Todos os comandos ':' podem ser abreviados pela sua letra inicial, como :l arquivo a assim por diante. Detalhes de outros comandos podem ser encontrados na documentação on-line do Hugs que pode ser lida usando um Web browser, como Netscape, Opera, Konqueror ou Internet Explorer.
Hugs pode ser conectado a um editor de textos "default", assim comandos como :edit e :find usam este editor. Isto pode ser determinado pela sua configuração local. O editor de texto default do Unix é o vi; nos sistemas Windows o Notepad pode ser usado. Detalhes de como o comando :set pode ser usado para alterar o editor default será explicado mais adiante neste tutorial.
Usando o comando :edit no Hugs causa uma chamada do editor de textos no arquivo apropriado. Quando o editor é encerrado, o arquivo atualizado é carregado automaticamente. No entanto é mais conveniente deixar o editor executando em uma janela separada e recarregar o arquivo usado:
Dessa forma o editor deixará aberto o arquivo facilitando as modificações.
Daremos agora alguns exercícios introdutórios usando Hugs nos primeiros programas de exemplo.
Tarefa 1
Carregue o arquivo FirstLiterate.lhs no Hugs, e avalie os seguintes expressões:
Com essa base, você pode explicar o que é a função $$?
Tarefa 2
Use o comando Hugs :type para saber o tipo de cada um desses exemplos, incluindo $$.
Tarefa 3
Qual o efeito de se digitar cada uma das expressões abaixo.
Tente explicar os resultados que você obteve
Dizemos no Capítulo 1 que o Haskell tem vários tipos embutidos, como integers e listas e funções sobre esses tipos, incluindo funções aritméticas, funções de manipulação de listas, map e ++. Estas definições estão contidas na standard prelude, prelude.hs. Quando Haskell é usado, o default é carregar a biblioteca prelude, como pode ser visto na figura 2.3 a linha:
Reading file: "C:\hugs\lib\Prelude.hs";que precede o processamento do arquivo FirstLiterate.lhs no qual Hugs foi chamado.
Como Haskell foi desenvolvidoa mais de uma década, o prelude também evoluiu. Começou pequeno, e com o tempo algumas das funções usadas na biblioteca padrão foram movidas para ele, para dar mais liberdade de inclusão de novas funções, quando necessário.
Além das bibliotecas padrão, a distribuição Hugs contribui com várias bibliotecas incluídas que suportam concorrencia, animações funcionais e assim por diante. Outros sistemas Haskell também contribuem com outras bibliotecas, mas todos os sistemas suportam as bibliotecas padrão.
Para trabalhar com as bibliotecas nós precisamos aprender algo sobre módulos em Haskell, que veremos agora.
Uma parte típica de um software de computador contém milhares de linhas código. Para poder gerenciar esse código, precisamos quebrá-lo em pequenos componentes, que chamamos modulos (modules).
Um module tem um nome e contém uma coleção de definições Haskell. Para introduzir um módulo chamado Ant, precisamos começar o programa com a texto:
module Ant whereUm módulo também pode importar definições de outros módulos. O módulo Bee importará as definições de Ant incluindo uma estrutura import, assim:
module Bee whereA estrutura import significa que poderemos usar todas as definições de Ant quando criamos definições em Bee. Por esse comportamento dos módulos, nós adotamos as convenções abaixo:
O mecanimo de módulos suporta várias bibliotecas discutidas na seção 2.3, mas podemos também incluir codigo escrito por nós mesmos ou por alguém.
O mecanismo de módulos permite controlar quais definições são importantes e também quais são disponíveis ou exportáveis por um módulo para uso em outros módulos.
Agora estamos em condições de explicar porque o prompt do Hugs aparece como Main> . O prompt mostra o nome do módulo de mais alto nível correntemente carregado no Hugs, e na ausência de um nome para o módulo, ele é chamado de módulo 'Main' (principal).
Nenhum sistema pode garantir que o que você digita está correto. Hugs não é excessão. Se alguma coisa está errada, em uma mensagem de erro ou em um script, você pode receber uma mensagem de erro. Tente digitar
2+(3+4no prompt do Hugs. Esse é um erro de sintaxe.
A expressão falta parênteses: depois do '4', um fecha parênteses está faltando, para fechar o parêntese aberto antes do '3'. A mensagem de erro diz que o que se seque ao '4' é inexperado:
ERROR - Syntax error in expression (unexpected end of input)
De forma similar, digitando 2+(3+4)) resulta na mensagem
ERROR - Syntax error in input (unexpected `)')
Agora tente digitar a seguinte expressão
double squareEsse é um erro de tipo, uma vez que double é aplicado à função square, sendo que ela pede um integer
ERROR - Type error in applicationA mensagem indica que alguma coisa do tipo Int era experado, mas alguma coisa do tipo Int -> Int foi apresentada no lugar. Nesse caso, double espera algo do tipo Int como argumento, mas square, do tipo Int -> Int foi encontrado no lugar de um inteiro.
Quando recebemos um erro como o descrito acima, precisamos olhar como o termo, neste caso square do tipo Int -> Int, não confere no contexto no qual é usado: o contexto é dado na segunda linha (double square) e o tipo requerido pelo contexto, Int, é dado na última linha.
Erros de tipo nem sempre nem sempre são mensagens bem estruturadas. Digitando 4 double ou 4 5 receberemos a mensagem
ERROR - Illegal Haskell 98 class constraint in inferred typeSerá explorado posteriormente detalhes sobre essa mensagem. Por hora é suficiente interpretar esse erro como Erro de tipo.
Tente digitar a expressão
4 `div` (3*2-6)Não existe divisão por zero. Sendo assim recebemos a mensagem
Program error: {primQrmInteger 4 0}indicando que a divisão de 4 por zero ocorreu.