Mostrando postagens com marcador programação funcional. Mostrar todas as postagens
Mostrando postagens com marcador programação funcional. Mostrar todas as postagens

segunda-feira, 24 de março de 2014

Haskell: Operações Recursivas em Listas

Fala galera, tudo tranquilo?

Hoje o assunto é bem bacana, venho fazendo uma listinha de exercícios marotos em Scala, e estou aprendendendo muito. Hoje o assunto é recursividade, de novo esse assunto? Sim isso está mudando minha vida ou mesmo a forma como penso. (Exagerando rs)

Então, vamos fazer em Haskell?

A ideia é simples, quero deixar bem claro e simples as operações em listas imutáveis usando recursividade, já expliquei algo sobre listas imutáveis aqui.

Bom, vamos começar com um problema, que tal fazermos um map* em uma lista.

* = Para quem não sabe, mapear uma lista é transformar cada valor da lista atual, em um valor que passará através de uma determinada função.

Crie um novo arquivo, double.hs, como não falo há pouco de tempo de Haskell, nos meus primeiros posts, você consegue ver como instalar o interpretador Hugs.

Vamos ao double.hs:

double [] = []
double (head:tail) = head * 2 : double tail

Bom, isso aí já torna a compreensão pouco simples, mas vou explicar, entenda:  double [] = [] é a nossa guarda, ou seja, um ponto onde devemos parar a execução da função. Já falei muito a respeito em posts mais antigos.
Já na segunda linha, vemos algo novo, mas acredito ser bem expressivo, double (head:tail), ali estamos separando a cabeça da lista, de seu corpo, faremos uma operação na cabeça (head *2) e concatenaremos com o corpo, mas passando o corpo como argumento da função double, repetiremos esse processo novamente, isso é incrível e simples.

Para exercitar, primeiro vamos deixar nosso double mais genérico, pois podemos querer fazer outros tipos de map em lista, crie um arquivo mapear.hs:

mapear f [] = []
mapear f (x:xs) = (f x) : mapear f xs

Pronto, agora nossa função está apta a receber outras funções a serem aplicadas a lista, você pode testar no Hugs.

Vá ao seu terminal, caminhe até o diretório do arquivo e digite: hugs mapear.hs

Para construir listas em Haskell, você pode usar de duas formas:

[1,1,2,3,5,8]
1 : 1 : 2 : 3 : 5 : 8 : []

Agora é só passar os parâmetros para sua função: mapear (*2) (1 : 2 : 3 : [])

Use os parênteses para "separar" os argumentos. Tudo certo! (Ou deveria estar).

Vamos evoluir mais um pouco, outra das operações básicas que podem ser efetuadas com lista é o Filter, onde você filtra os elementos da lista e só extraí o que "passar pelo filtro". Basicamente vamos passar uma validação para cada elemento da lista, e como fazer? Crie um arquivo filtro.hs e vamos codar nele:

filtro :: (a -> Bool) -> [a] -> [a] 
filtro f [] = []
filtro f (x:xs) | f x = x : filtro f xs
                | otherwise = filtro f xs

Trabalhamos com quase a mesma forma de aplicar a função do mapear, porém fizemos uma verificação, onde:

  •  | é a nossa verificação;
  • caso f x retorne false:
    • devolvemos só  filtro f xs;
  •  caso f x retorne true:
    • concatenamos a cabeça x ao filtro f xs;


Ou seja, como vamos navegando na lista, cada hora a cabeça é o elemento posterior, isso é muito simples. Já falei de estruturas de verificação.

O desafio de hoje é meio trabalhoso, caso a preguiça domine vai ter que esperar eu fazer aqui também pra disponibilizar no Github. Você deve implementar um Flatten, ou seja, caso receba uma lista de listas, deve devolver uma lista contendo todos os elementos das listas internas.

É isso aí gente, qualquer dúvida comente abaixo ou email-me: abner.terribili@lambda3.com.br.



segunda-feira, 3 de março de 2014

C#: Um suporte a funções

Fala aí galera!

Seguindo os posts atuais sobre C#, em uma das minhas aulas com o Jonas, descobri uma das maravilhas de C# e seu "pequeno" suporte a programação funcional.

Hoje faremos algo bem prático. Vamos criar um exemplo genérico de um método que recebe três parametros, sendo eles: int, int, função.

Comecei hoje a leitura de um livro muito bacana: Código Limpo - Robert C. Martin. (Que já me proíbe a criação de uma função que recebe três parâmetros, mas vamos relevar isso rs) Parece muito bom, como o nome diz é um livro que através da pratica deliberada, nos "promete" o conhecimento para distinguir um bom código de um código ruim, digo isso como dica a todos vocês leitores, e que também é mais uma das minhas lições no desenvolvimento de software. (E o VIM galera, estão usando?)
Se ainda faltam alguns conceitos de paradigma funcional, dê uma lida nos meus posts anteriores, sempre estou com esse tema em pauta.

Vamos a prática.
Crie um projeto novo no seu Visual Studio e dê um nome bacana e objetivo.

Dei o nome de AprendendoFunc, na minha opinião, objetivo.

Segundo passo, vamos criar os Testes:

Cria uma nova Solution, dentro dela crie um projeto Class library e outro Projeto de Test Unit. Então a primeira coisa que vamos testar é uma possível soma entre dois números:

...
[TestMethod]
public void DeveSomarDoisNumeros()
{
    Func<int, int, int> funcaoSoma = (x, y) => x + y;

    Assert.AreEqual(120, new Calculadora().Calcula(60, 60, funcaoSoma));
}

Claro que nosso teste apresentará alguns erros, porém com ele já sabemos qual o nosso objetivo.

Nossa classe Calculadora, deve possuir um método que recebe 3 parâmetros. A função acima (funcaoSoma) é uma função que vem lá da matemática, entenda:

Func<parametro, parametro, tipoRetorno> nomeFuncao = (parametro, parametro) => funcao;

Ficou simples de entender, certo? Passamos dois números inteiros e recebemos o resultado da operação da função passada, isso é incrivel! Dizem as más linguas, ou boas, que o F# tem um pézinho aí!

Agora vamos implementar nossa classe Calculadora:
...
public class Calculadora()
{
    public int Calcula(int primeiroNumero, int segundoNumero, Func<int, int, int> funcao)
    {
        return funcao(primeiroNumero, segundoNumero);
    }   
}

Pronto, nossa Calculadora está pronta para receber os parâmetros corretos. Agora rode seus testes e assegure-se do resultado estar correto.

Feito isso, crie mais um método de teste que deve executar a multiplicação de dois números. É muito fácil né?

Bom, e se precisarmos fazer algum tipo de comparação? Um exemplo prático, ao tentar dividir o primeiroNumero pelo segundoNumero, poderemos encontrar um problema caso segundoNumero = 0, para evitar isso, podemos criar mais um método:

public class Calculadora(){
    ...
    public int VerificaECalcula(int primeiroNumero, int segundoNumero, Predicated<int> verificacao, Func<int, int, int> funcao)
    {
        if(verificacao(primeiroNumero, segundoNumero)
        return funcao(primeiroNumero, segundoNumero);
    return 0;
    }
}

Entenda: Predicated recebe apenas um parâmetro e retorna um booleano, é amplamente usado para verificações, acredite. Temos também o Action, que é void, mas não é útil no nosso exemplo.
Vamos ao teste?

...
[TestMethod]
public void DeveCalcularDivisaoComVerificacao()
{
    // Aqui podemos fazer as três etapas em uma só linha: Setup, Execução e Verificação
    Assert.AreEqual(0, new Calculadora().VerificaECalcula(100, 0, (y) => y > 0, (x, y) => x / y));
}

Pronto, assim podemos passar a função de verificação e ainda a função de execução, isso sim é incrível.

Bom galera, por hoje é só, qualquer dúvida email-me: abner.terribili@lambda3.com.br ou comente abaixo!


quarta-feira, 29 de janeiro de 2014

Haskell: Tipos Compostos com Tuplas

E aí galera, tudo tranquilo?
Depois de um dia de praia e muito calor, decidi escrever rs.

De acordo com o meu último post a respeito de Haskell, falei sobre Tuplas. Será importante saber a respeito para dar continuidade.

Hoje tirei a noite pra falar a respeito dos Tipos Compostos e darei alguns exemplos usando Tuplas.

type
No Haskell quando usamos a função type criamos novos Tipos. Semelhante ao typedef do C.

É algo bem básico de entender. Imagine que você precisa definir um "novo" tipo, ou seja, quer definir um novo nome para um determinado tipo de dado:
type Numero = Float
raiz :: Numero -> Numero
raiz a = sqrt(a)


Na primeira linha, nós definimos o tipo e o nomeamos. Já na segunda linha definimos os parâmetros de entrada e saída da função raiz. No fim, tiramos a raiz. Nessa função, o type Numero equivale ao Float do Haskell.

Pô, e onde isso é útil?
Bom, durante meu processo de aprendizado em Haskell, pude ver que o type unido a Tupla fica muito mais interessante. Vamos ver?

Criemos a situação onde preciso de uma "objeto"(type) com seu "atributos". Como podemos definir um cachorro?
Nome
Raça
Idade
Peso

Acredito serem atributos válidos. Vamos usar o Haskell:
-- Define os nomes dos atributos do cachorro
-- String = [Char], ou seja um array de Char
type Nome = String
type Raca = String
type Idade = Int
type Peso = Float


-- Define Cachorro com seus respectivos atributos
type Cachorro = (Nome, Raca, Idade, Peso)

-- Criando um cachorro, um não dois
c_duda, c_pingo :: Cachorro
c_duda = ("Duda", "Teckel", 12, 2.5)
c_pingo = ("Pingo", "Poodle", 1, 4.1)


Com isso nós podemos trabalhar com "objetos" no Haskell.
Vamos ao exemplo prático. Crie um arquivo, types.hs, para começar digite em seu interior o conteúdo lido acima (Types até a criação do Cachorro), depois adicione o conteúdo abaixo:
-- Funções para retorno dos atributos
-- A função get_nome, recebe um Cachorro e devolve o seu nome
get_nome :: Cachorro -> Nome
get_raca :: Cachorro -> Raca
get_idade :: Cachorro -> Idade
get_peso :: Cachorro -> Peso


-- n = nome, r = raça, i = idade, p = peso
get_nome (n, r, i, p) = n
get_raca (n, r, i, p) = r
get_idade (n, r, i, p) = i
get_peso (n, r, i, p) = p


Bom, agora é só testar! Salve seu arquivo e vamos ao terminal e ao diretório do seu arquivo:
hugs types.hs

Main> c_duda
c_duda = ("Duda", "Teckel", 12, 2.5)


Main> get_nome c_duda
"Duda"


Main> get_idade c_pingo
1


E teste o que mais você quiser! Muito louco né?

E da pra fazer uma coisa mais legal ainda:
Main> get_nome ("Teka", "Basset", 3, 3.1)
"Teka"


Mas como assim? Nós criamos* um Cachorro e retornamos seu Nome.
*Entenda que no Haskell só trabalhamos com funções.
Não se esqueça do o Cachorro recebe uma tupla-4. Caso se esqueça desse pequeno detalhe, verá algo assim:


Bom galera, por hoje é só! O arquivo do exercício acima esta no meu GitHub. Só reforçando uma dica anterior , que tal aprender a usar um editor top?
Vim
Emacs

Qualquer dúvida, comente abaixo ou email-me: abner.terribili@gmail.com.

Valeu!



domingo, 26 de janeiro de 2014

Haskell: Apresentando Tuplas

E aí galera, hoje o assunto é bem interessante. Vou mostrar um pouco a respeito das Tuplas.

("Abner Terribili", 22, 72.4, "Verde")
Algo como Nome, Idade, Peso e Cor favorita. Imagine essa tupla como um objeto e seus respectivos atributos, do Java.

Esse exemplo acima é conhecido como Tupla. (Definição boa do Wikipédia, não deixe de ler)

Em Haskell podemos criar funções que manipulam um conjunto de dados. Esse conjunto, heterogênio de dados, tem como objetivo representar uma relação entre seus dados, de forma que a captura do mesmo seja atravês da posição, tal como um Array.

O número de objetos dentro da tupla, define o tamanho da tupla. Ou seja, caso avaliemos a tupla acima, teremos uma tupla-4, veja: 
("Abner Terribili", 2272.4, "Verde")

Caso nossa tupla possua somente:
("Abner Terribili", 22);

Teremos uma tupla-2. Podendo chegar até a tupla-n, dependendo somente da quantidade de elementos em seu interior.

Como no Haskell não somos "obrigados" a definir os tipos dos dados, o interpretador reconhece de forma automática, ele reconhecerá os respectivos elementos da seguinte maneira:

Abner Terribili   String  
22 Int
72.4 Float
Verde String

Lembrando que uma String é uma lista. (Sequência de caracteres)

A principal aplicação das tuplas é definir uma função que receba ou retorne mais de um valor e, geralmente, do tipo heterogênio. Apesar das suas vantagens, a tupla tem uma estrutura estática, ou seja, uma vez criada, não pode ser modificada. (Definição Livro: Haskell Uma abordagem prática)

Por padrão as tuplas-2, no Haskell, têm algumas duas pré-definidas, sendo elas:
fst
snd;

fst (first) = tem como função retornar o primeiro elemento da tupla-2.
snd (second) = tem como função retornar o segundo elemento da tupla-2.

Vamos testar? Vá até o seu terminal e entre no interpretador Hugs, digitando apenas:
$ hugs

Logo verá o Terminal Hugs, você pode testar vendo o retorno da função:
Main> fst (1, 2)
1

A função fst retornou o primeiro elemento da tupla-2 (1, 2). Agora teste o snd também. Gostou?

Imagine que você tem que calcular a multiplicação e soma de dois números (x, y).  Normalmente faríamos duas funções:
multiplicacao Int -> Int -> Int
multiplicacao x y = x * y
soma Int -> Int -> Int
soma x y = x + y

Pô, acho que uma tupla resolve e economiza na escrita, olha lá:
-- Na definição dos parâmetros, escrevemos que a função vai receber uma tupla-2 e devolverá outra tupla-2
multiplicacao_soma :: (Int, Int) -> (Int, Int)
multiplicacao_soma (x, y) = (x * y, x + y)

E aí, foi mais simples? Na minha opinião, sim!
Com apenas uma função resolvemos um problema "composto".

Teste o exercício acima, vai gostar do resultado, mas não se esqueça da passagem de uma tupla como parâmetro. Exemplos: (1, 2), (99, 27).

Se estiver com tempo, reescreva as funções "fst" e "snd". A resposta está no GitHub.

A dica para esse exercício é usar o "_" (Underscore), como variável anônima, imagine-o como um coringa, você não precisa definir o tipo da variável que não terá utilidade para você. Ou seja, o argumento "_" tem seu conteúdo desconsiderado pelo interpretador.

Esse post ficará por aqui, mas já estou preparando o próximo pra falar um pouco de "Tipos compostos com Tuplas".

E minha dica de hoje é um app, ou uma Android Activity, escrita em Haskell (!!!) , legal não? 

Qualquer coisa, email-me: abner.terribili@gmail.com ou comente abaixo.

Cheers!



terça-feira, 21 de janeiro de 2014

Haskell: Recursividade

Fala aí galera, hoje peguei firme no estudo e estou escrevendo esse post com o Vim! :D

Vou falar mais um pouco de Haskell e o assunto hoje é Recursividade.

A recursividade é a definição de uma subrotina (função ou método) que pode invocar a si mesma (Definição Recursividade). A Matéria sobre Recursividade da Wikipédia está impecável, não deixe de ler.

Onde isso é útil?
Imagine, você precisa calcular a soma dos n primeiros números. Ou seja, precisa escrever uma função que receberá como parâmetro um número n, você terá que somar esse número n a todos os seus antecessores, para que não seja feito através da iteração, podemos usar a recursão.

E a idéia é simples, vamos as definições:
soma (n) = { 1                         : n = 1
                  { soma (n - 1) + 1 : n > 1

soma 10 = 1+2+3+4+5+6+7+8+9+10 = 55

Poxa, mas como minha função sabe onde deve parar?
Devemos definir um aterramento, ou seja, um ponto onde a função deva parar.(Uma Guarda!)

De acordo com a definição matemática de indução, registrada acima, para n = 1, temos como resultado o número 1, para n > 1, nós invocamos novamente a função soma.

Vamos codar, para isso crie um novo arquivo em seu diretório favorito, de o nome de soma_recursividade.hs e digite em seu interior:

soma Int -> Int
soma 1 = 1
soma n = soma (n-1) + n


Ou seja, caso nosso n = 1, a função soma 1, entra em ação e retorna 1. Caso n > 1, a função soma(n), entra em ação, fazendo uso de si mesma para executar a tarefa de soma, isso se chama recursividade.

Podemos compreender o que o Hugs faz, interpretando essa função como escadaria da recursividade, quer ver?
soma 5
= (soma 4) + 5
= ((soma 3) + 4) + 5
= (((soma 2) + 3) + 4 ) + 5
= ((((soma 1) + 2) + 3) + 4) + 5


Agora,o seu interpretador resolverá a função de acordo com as prioridades:
= ((((1) + 2) + 3) + 4) + 5
= (((3) + 3) + 4) + 5
= ((6) + 4) + 5
= (10) + 5
= 15

Teste você mesmo, caminhe até o local do arquivo e:
hugs soma_recursividade.hs
Main> soma 10
15

Pronto! Simples? Talvez meio complicado para compreender de início, mas quando entra na cabeça, parece até simples. rs

Vou até deixar um exercício, ou melhor, dois!

Exercício 3:
O que acha de aprender a usar o Vi ? ou o Vim (Vi improved)?
É simples, poderoso e um software livre!

Eu treinei com esse aí:
Tutorial Básico Vim

Logo, quando eu estiver mais confortável, escrevo um post a respeito do Vim.

Exercício 4:
Crie uma função, em Haskell, que receba um inteiro como parametro e calcule o seu fatorial.

Vamos as definições matemáticas:
O Fatorial, para quem não lembra, é o número corrente multiplicado pelo fatorial de seu antecessor.
fatorial (n) = { 1 : n = 0
                    { fatorial (n - 1) * n  : n > = 1

Bom, se rolar alguma dúvida, não se esqueçam de comentar abaixo ou email-me: abner.terribili@gmail.com. A resposta para o exercicio 4 está no meu GitHub, nome exercicio_4.hs.

Até mais galera!



sábado, 18 de janeiro de 2014

Haskell: Operadores Relacionais e Estruturas Condicionais


Fala aí galera, acho que to gostando de falar/aprender sobre Haskell :)

No post passado falei a respeito Tipo de Dados e Introdução a Funções, se não o leu, favor ler, complementará o material de hoje.

Hoje, vou falar a respeito Operadores RelacionaisEstruturas Condicionais.
Para começar, vamos entender o que fazem os Operadores Relacionais. Eles têm a responsabilidade de realizar comparações, trabalhando com valores lógicos:
São eles:

Operador Descrição
      > maior do que
      >= maior ou igual a 
      < menor do que
      <= menor ou igual a  
      /= diferente de

Vou deixar alguns exemplos, somente para fins didáticos. Vamos fazer a soma de dois números e verificar as operações básicas relacionais entre eles:

soma x y | x + y > 0 = 1
         | x + y >= 0 = 2
         | x + y < 0 = 3
         | x + y <= 0 = 4
| x + y /= 0 = 5 

-- Se a soma de x y for maior do que 0, retorna 1.
-- Se a soma de x y for maior ou igual a 0, retorna 2.
-- Se a soma de x y for menor do que 0, retorna 3.
-- Se a soma de x y for menor ou igual a 0, retorna 4
-- Se a soma de x y for diferente de 0, retorna 5

Estruturas Condicionais nada mais são do que condições que controlam se um determinado trecho de código será executado ou não. Exemplo, vamos supor que sua equação só trabalhe com números positivos. Normalmente faríamos algo parecido com:

sua_funcao seu_numero se seu_numero > 0 = √seu_numero
        caso contrário = 0
Aqui no Haskell, não é muito diferente, na verdade, é idêntico!
O Haskell também possui tipos de dados Booleanos (True / False). Podemos trabalhar com eles, para melhorar nossas estruturas condicionais.

Vamos aos exemplos, crie um arquivo chamado raiz_quadrada.hs e insira o código abaixo:

-- Você não precisa definir os tipos dos parâmetros de entrada e saída toda vez, mas para fixar o conceito, pratique!
raiz_quadrada :: Float -> Float
raiz_quadrada x | x > 0 =  sqrt(x)


Vamos entender, aquele pipe '|' é o nosso 'se', mais conhecido como 'if'. Tem a função de verificar o parâmetro de entrada. O 'x', é o nosso parâmetro de entrada. Caso o número seja positivo, a função 'sqrt()' pré-definida na Biblioteca do Haskell, Prelude, vai fazer o 'favor' de calcular a raiz quadrada do 'x'.

Bom, vamos fazer um something more nessa função.

Caso o número seja negativo ou igual a 0, vamos retornar 0.
raiz_quadrada x | x > 0 = sqrt(x)
                | otherwise = 0

Bom, o que é 'otherwise'?
Nada mais é do que 'caso contrário', significa que se nenhuma das condições acima for satisfeita, execute a condição 'otherwise'.

E se minha função tiver que trabalhar com uma condição 'composta' ?
Seria limitar ainda mais sua entrada, nós podemos usar os operadores abaixo:

Operador Descrição
     && e / and, tem o objetivo de verificar se ambas condições são verdadeiras.
      || ou / or, tem o objetivo de verificar apenas uma das condições é verdadeira.
     not não / not, tem o objetivo de negar o booleano, converte true/false e vice versa. 

Abra seu arquivo raiz_quadrada.hs novamente, vamos fazer mais algumas alterações:
raiz_quadrada :: Float -> Float
raiz_quadrada x | x > 0 || x == 0 = sqrt(x)
                | otherwise = 0

-- Poderíamos otimizar para x >= 0, só não fiz isso para seguirmos no exemplo.

Execute sua função no Terminal, digitando:
hugs raiz_quadrada.hs

Você verá a telinha de apresentação do Hugs, informe o número de entrada da sua função:
Main> raiz_quadrada 2
1.41414

Agora com um número negativo:
Main> raiz_quadrada (-1)
0

Lembre-se de inserir o '()', para que o sinal de '-' faça parte do número real.

Se tiver alguma dúvida sobre como executar o arquivo, ou mesmo instalar o Interpretador Hugs, olhe aqui! Nos próximos posts evitarei ficar falando disso :)

Acredito ter dado uma pequena, mas boa introdução a 'Operadores Relacionais e Estruturas Condicionais', espero que tenham gostado.

Deixarei 2 exercícios abaixo, que não são de minha autoria (Claudio C. de Sá e Márcio F. da Silva), apenas as resoluções são de minha autoria, se tiverem alguma dúvida ou sugestão, pode comentar ou mesmo me enviar um email: abner.terribili@gmail.com. As respostas estão no meu GitHub.

Exercício 1:
Fornecidos três valores, a, b e c, escreva uma função que retorne quantos dos três são iguais. 3 para os 3 iguais. 2 para dois iguais e 0 para nenhum igual.

Exercício 2:
Fornecidos três valores, a, b e c, elaborar uma função que retorne quantos desses três números são maiores que o valor médio entre eles. 3 para os 3 maiores. 2 para dois maiores e 0 para nenhum maior.

Boa sorte!

Já que nosso primeiro HelloWorld foi Matemático, que tal fazermos um HelloWorld de verdade?

Crie um arquivo chamado hello_world.hs e digite em seu interior:
hello_world :: IO()
hello_world = putStrLn "Hello World!"
-- Mais para frente entro em detalhes desse Tipo de Dado IO()

Agora vá em seu Terminal, caminhe até o local do arquivo e digite:
hugs hello_world.hs

Teremos essa bela saída, criada por B. W. Kernighan
Main> hello_world
Hello World!


Agora, se você curtiu esse 'Hello World!', que tal implementa-lo em 'todas' as linguagens?
Deve ser um exercício muito construtivo e interessante!

A dica de hoje é exatamente essa: Programa Olá Mundo

Bom, agora acabou mesmo, até a próxima galera!


quinta-feira, 16 de janeiro de 2014

Haskell: Tipo de dados e Introdução a Funções



E aí galera, olha eu aqui de novo.

Hoje vou falar mais um pouco de Haskell. Caso você não saiba do que estou falando, dê uma olhadinha no meu primeiro post .

As funções que desenvolvemos no Haskell têm um tipo de dado de retorno e de entrada, podendo ser:

Tipo Descrição Exemplo
Bool Booleano True/False
Int Inteiro com Domínio Limitado 1900
Integer Inteiro com Domínio Ilimitado 01123581321345589144233
Float Real 3.14159265359
Char Caractere 'h'
String Cadeira de Caracteres 'Haskell'
Void Vazio '_' (underscore. Mais pra frente, entrarei em detalhes)


O Haskell, como padrão, em seu compilador ou interpretador, tem um sistema de dedução automática de tipos em todas as funções que não tiveram seus tipos definidos. Ou seja, você não é 'obrigado' a definir os tipos de dados que serão utilizadas em suas funções. E sim, o Haskell possui uma disciplina rigorosa de tipos de dados, diz-se fortemente tipada. Com isso, sabemos que todas as variáveis, funções e constantes têm somente um tipo de dado e sempre podemos determinar o seu tipo. Certo?

Bom, caso você queira determinar os tipos de dados que serão aceitos por sua função, é bem simples, vamos ao exemplo teórico:

Definição do tipo de dados que serão aceitos pela função nome_funcao:
nome_funcao :: Tipo_Arg_1 -> Tipo_Arg_2 -> Tipo_Saida

Então, 'nome_funcao' é o nome da função, '::' operador de instância de tipos, 'Tipo_Arg_X' (Tipo_Arg_1, Tipo_Arg_2) é tipo de dado de entrada e por fim 'Tipo_Saida' é tipo de dado que será retornado por sua função.

No exemplo prático, talvez fique mais simples:
soma :: Int -> Int -> Int

soma x y = x + y

Ou seja, nossa função 'soma' receberá dois argumentos do tipo Int, 'x' e 'y', e terá como retorno um tipo 'Int'.

Nota: Lembre-se um pouco da Matemática, onde ƒ(x, y) = x + y.

Crie um novo arquivo com o nome de 'soma.hs' e digite o código acima dentro desse arquivo, não se esqueça de usar um editor de texto que tenha como padrão ASCII.

Teste no seu terminal:
hugs soma.hs

Deve aparecer a famosa apresentação do Hugs, digite:
Main> soma 3 4

7

Se sentir alguma dificuldade, baixe o arquivo do meu repositório GitHub: github.com/aterribili/Haskell/blob/master/soma.hs

Mais fácil impossível rs, talvez minha didática ainda não esteja tão boa quanto desejo, mas vou melhorando :)

E, para finalizar, as dicas de hoje são:

Interpretador Haskell Online TryHaskell (Gratuito)
http://tryhaskell.org/

Existe no GitHub, um repositório chamado /free-programming-books, onde nada menos que 16.000 pessoas estão colocando seus tutoriais de programação para compartilhar seus conhecimentos.

https://github.com/vhf/free-programming-books

E lá, tem algo muito bacana sobre Haskell:
https://github.com/taylorrf/learnhaskell
http://haskell.tailorfontela.com.br/

A galera ainda está traduzindo, mas já tem um bom material para começar. Vou dar um fork e tentar a ajudar a traduzir. Até mais galera! Qualquer dúvida, por favor, pergunte abaixo ou me enviem um email: abner.terribili@gmail.com. Vou criar um repositório GitHub e compartilhando os exercícios lá.

Atualizando: Repositório criado, para acompanhar os exercícios: github.com/aterribili/Haskell


terça-feira, 14 de janeiro de 2014

Haskell: O HelloWorld Matemático

E aí galera, vou me apresentando aos poucos. 
Me chamo Abner Terribili, atualmente tenho 22 anos, estou planejando iniciar este blog há algum tempo (+/- 2 anos) Sou programador há aproximadamente 3 anos, já trabalhei com Delphi, Java, HTML5, JS, Obj-C, C++, Android, e por aí vai. Tenho como maior objetivo salvar o mundo, ainda mais se for codando :). Meu objetivo aqui é deixar minhas experiências e ajudar aqueles que precisam de ajuda. Não possuo vasta experiência na área, e com esse blog, além de ajudar quem precisar, possivelmente aprenderei muito. Vou escrever a cada nova experiência que eu participar. E tentarei ao máximo que isso seja frequente.

Bom, com o tempo eu melhoro essa apresentação, estou empolgado para começar a codar com vocês. 

Hoje comecei a estudar algo novo, mais voltado para a Matemática, do que para programação. Estava procurando algum livro bacana em uma loja e acabei encontrando esse: Haskell : Uma abordagem prática de Claudio C. de Sá e Márcio F. da Silva. Cara, que coisa legal essa história de paradigma funcional. Não entrarei em extensos detalhes, para não ficar complicado para mim e para vocês.

O que é paradigma funcional ?
- É um paradigma de programação que trata a computação como uma avaliação de funções matemáticas e que evita estados ou dados mutáveis. Ela enfatiza a aplicação de funções, em contraste da programação imperativa, que enfatiza mudanças no estado do programa. (Wikipédia: Paradigma Funcional)

Depois de dar uma passadinha aí por cima do texto do Wikipédia (que é pequeno), vamos a instalação do interpretador Hugs. Escolhi o Haskell, justamente por ouvir falar bem a respeito (Jean Baro). Clique no link caso tenha interesse em maiores informações a respeito.


O interpretador Hugs é uma implementação de Haskell, foi escrito na linguagem C e não compila código algum, somente interpreta. Após a instalação, que é bem simples, só acessar a guia “Downloading” do site acima e seguir os passos descritos.

Testei em um ambiente Unix/Mac, foi bem simples, fiz a instalação via Terminal, utilizei o Homebrew, que é um gerenciador de pacotes (Homebrew).

Comando para instalação do Hugs no Mac, via Terminal:
brew install hugs

Ele acabou pedindo um complemento (GCC):
brew install apple-gcc42

Para instalar no Linux:
apt-get install hugs

Aqui tem uma discussão legal a respeito da Instalação do Hugs no Windows:
Interpretador Haskell Windows e Online

E tudo certo!

Para escrever programas em Haskell, basta qualquer editor compatível com ASCII. Atualmente utilizo o Sublime Text 2 (Sublime Text 2).

Finalizando com exemplo:
Imagine que você tem que calcular a área de uma circunferência, então para iniciarmos nosso exercício vamos definir: 




- Área da circunferência = π * r ², onde π = 3.14159 e r = distância do centro da circunferência até alguma extremidade (raio).

Para iniciar o exercício, crie um diretório em algum local de sua preferência, no Desktop fica mais fácil acessar.

Após criar o diretório, crie, também, um novo arquivo chamado area_circunferencia.hs. (Arquivos com extensão .hs são aplicativos Haskell) 

Abra o seu arquivo area_circunferencia.hs com o seu editor de texto favorito.

Insira as seguintes linhas:
p = 3.14159
area_circunferencia r = p * r * r

Ou utilize o valor do pi da própria biblioteca Prelude:
area_circunferencia r = pi * r * r

Caminhe, via Terminal/CMD, até o diretório do arquivo area_circunferencia.hs.

Execute o comando :
hugs area_circunferencia.hs

Verá algo como:



Pronto sua aplicação está pronta para receber entradas, teste a sua função: 
Main> area_circunferencia 2

Deverá ver algo como:
12.5663706143592

Se sentir alguma dificuldade, baixe o arquivo do meu repositório GitHub: github.com/aterribili/Haskell/blob/master/area_circunferencia.hs

Nota: Na prática descobri que a biblioteca do Hugs, Prelude, já armazena um valor para o π (pi). Basta colocar pi no código. (Hugs.Prelude.pi)

O Haskell passou seu valor para o raio e fez o cálculo para você. Essa é a principal diferença do paradigma funcional, ele executa funções, como na matemática, você não precisa “mandar” ele fazer algo, precisa apenas informar os valores. Bom, espero que isso ajude quem tem interesse em Haskell e quem ainda não tem também. :) Vou melhorando e estou aqui para maiores dúvidas.