Hora de iniciarmos um estudo sobre Listas, uma estrutura bastante poderosa na linguagem Haskell.

Uma das vantagens das listas é que elas podem ser infinitas (o que é realmente útil), porém elas devem ser homogêneas, ou seja, todos os elementos dela devem ser de um mesmo tipo.

NOTA: Onde eu achar necessário, colocarei a resposta do interpretador, que estará em verde.

Criar uma lista é bem simples, basta colocar seus elementos entre colchetes:

[1, 2, 3]

Listas também podem ser criadas sem nenhum elemento:

[ ]

Para adicionar novos elementos ao início da lista, basta usar o operador cons (“:”):

0 : [1, 2, 3]
[0, 1, 2, 3]
0 : 1 : 2 : 3 : [ ]
[0, 1, 2, 3]

Para concatenar duas listas, use o operador “++”

[0, 1, 2] ++ [3]
[0, 1, 2, 3]

Outras duas funções simples para listas são head e tail. A função head retorna o primeiro elemento da lista, enquanto tail retorna uma lista com todos os elementos exceto o primeiro:

head [0, 1, 2, 3]
0
tail [0, 1, 2, 3]
[1, 2, 3]

O número de elementos da lista se consegue usando a função length:

length [1, 2, 3]
3

Strings são apenas listas de caracteres, portanto todas as funções de lista valem para Strings:

['a','b','c']
"abc"

'a' : "bc"
"abc"

"ab" ++ "c"
"abc"

head "abc"
'a'

tail "abc"
"bc"

length "abc"
3

Blogged with the Flock Browser

Tags: , ,

Vamos começar hoje a ver algumas estruturas do Haskell, começando com as tuplas.

Em Haskell, é possível declarar pares de elementos, bastando apenas colocá-los entre parenteses, dessa forma:

(1, 7)

Para pegar o primeiro elemento da tupla, use fst:

fst (1, 7)

E para pegar segundo, use o snd:

snd (1, 7)

É possível generalizar esta estrutura e criar trios, quádruplas… Esta estrutura é chamada de tupla.

Tuplas não exigem que os seus elementos sejam todos do mesmo tipo, é possível juntar Strings, inteiros, o que você quiser (até mesmo outras tuplas):

(1, "String", (2, 'a'))

NOTA: fst e snd funcionam apenas com pares, se tentar utilizá-las com tuplas maiores, um erro é retornado.

Uma desvantagem das tuplas é que elas guardam um número finito de elementos, não podendo ter o número de elementos alterado, enquanto as listas (assunto para outro(s) post(s)) podem ser infinitas.

Blogged with the Flock Browser

Tags: ,

1. Onde aprender?
No site da linguagem Haskell há uma  boa coleção de livros e material on-line para se aprender Haskell, tanto para quem nunca programou, para quem tem experiência com linguagens imperativas e para quem já trabalhou com outras linguagens funcionais.

Eu estou seguindo o Haskell Tutorial for C Programmers, um tutorial muito bom para aqueles que, como eu, já está acostumado com linguagens imperativas. O autor faz comparações entre as linguagens funcionais e as imperativas, demonstrando as funcionalidades específicas da Haskell, com muitos exemplos bem explicados.

Outro tutorial é o Yet Another Haskell Tutorial, que estou vendo agora e também parece ser muito bom (o prório site da Haskell o indica como “o melhor”[1]).

2. O que baixar?

Existem várias implementações de Haskell (compiladores/interpretadores) na Internet, disponibilizadas gratuitamente. Mas apenas duas são largamente usadas: GHC e Hugs.
Ambas as implementações funcionam tanto como compiladores quanto interpretadores.
A primeira, mais utilizada, é considerada por muitos a implementação padrão do Haskell: é a que possui maior número de ferramentas e extensões e o código possui uma melhor performance, mas é a mais pesada das implementações (~33 Mb). O GHC possui também um interpretador (GHCi), que pode ser utilizado durante seus estudos.

Para quem está começando, e não precisa de todas as ferramentas que o GHC oferece, existe o  Hugs. Além de ser bem menor do que o GHC (existe até uma versão mini, de 1.4 Mb),  sua compilação rápida é boa para quem quer estudar a linguagem e vai recompilar código várias vezes.

3. Onde encontro mais material?

Em haskell.org há grande disponibilidade de livros e material on-line para aprender Haskell. Tem também links para mailing lists, artigos diversos sobre a linguagem, implementações da linguagem e informações diversas sobre a comunidade Haskell.

4. Links:

[1] http://haskell.org/haskellwiki/Learning_Haskell

Blogged with the Flock Browser

Tags: , ,

No último post (que ficou meio incompleto, confesso), comecei a falar um pouco sobre o paradigma da programação funcional.

Uma das coisas citadas é o fato de o programa ser tratado como um conjunto de funções matemáticas. O que isso quer dizer?

Para visualizar isso, vamos ao clássico exemplo do fatorial.

Matematicamente falando, n! (n fatorial) é o produto de todos os números menores ou iguais a n. Ou seja, o produto entre todos os números de 1 até n. Por exemplo: 5! = 1 * 2 * 3 * 4 * 5.

Observe que 0! = 1 já que o resultado de não se multiplicar nenhum número (identidade multiplicativa) é 1 (mais informações em http://en.wikipedia.org/wiki/Empty_product).

Normalmente existem 2 formas de se fazer isso: recursiva e interativa:

Recursiva:

int fatorial(int n)
{
    if(n <= 1)
        return 1;
    return n * fatorial(n - 1);
}

 
Interativa:

int fatorial(int n)
{
    int r = 1;

    while(n > 1)
        r *= n--;
    return r;
}

Isso em uma linguagem funcional (no caso, Haskell), ficaria como:

fatorial :: Int -> Int
fatorial 0 = 1
fatorial n = n * fatorial (n - 1)

Muito parecido com a versão recursiva em linguagens não-funcionais.

E, de fato, muito do que se faz em uma linguagem funcional é recursivo.

Porém, uma linguagem funcional normalmente oferece vários “artifícios matemáticos” para se trabalhar.

Em Haskell, por exemplo, isso poderia ser escrito como

fatorial :: Int -> Int
fatorial n = product [1..n]

ou seja, literalmente o que diz a definição: o produto entre todos os números de 1 até n.

Uma das principais vantagens disso é a redução da quantidade de código. Considerando que a declaração do tipo não é necessáriamente obrigatória (apesar de uma boa prática) a função pode ser implementada em apenas uma ou duas linhas, respeitando os padrões de identação e tudo mais.

Como o título do post sugere, começarei a abordar Programação Funcional. Ainda olhando para o título, pode-se perceber que essa é apenas a primeira de uma série de artigos. E olhando mais para o final do título, você poderá perceber que esta é apenas uma definição, ou simples explanação do que é o paradigma de programação funcional.

Então, vamos lá…

Programação funcional é o estilo de programação que trata as partes de um programa como funções matemáticas. Isso quer dizer que o programa não guarda estado, não possui variáveis, enfim, não tem nada que altere o valor. Tudo (ou quase) são funções.

Linguagens que seguem este estilo (como Haskell, por exemplo) tem as funções como tipos de “primeira classe”, isto é, você pode declarar funções, passá-las como parâmetros para outras funções, enfim, são tipos de dados como qualquer outro.

Outra característica da programação funcional é que normalmente as funções são puras, ou seja, não dependem de nenhum “efeito colateral”, como variáveis globais, passagem por referência, enfim, seu resultado depende apenas dos parâmetros de entrada.

Agora você deve estar se perguntando: “Por que eu iria querer usar uma linguagem que não tem variáveis?”.

Algumas das vantagens da programação funcional:

  • Não guardando o estado de nada, o compilador pode fazer otimizações normalmente inseguras em outro tipo de linguagem;
  • Normalmente as linguagens funcionais usam Lazy Evaluation, ou seja, só avaliam uma coisa se ela for realmente usada;
  • É eficiente em aplicativos multi-threaded, já que não há risco de que algo indesejado seja alterado.

Hello world!

21 Abril, 2008

Primeiro post do HaskellGuys. Nosso objetivo é escrever sobre Haskell e posts relacionados a Programação Funional.