Skip to content
13 changes: 6 additions & 7 deletions cap01-introducao/cap01-part01.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ Introdução

** Sobre este tutorial **

Bem-vindo ao Aprender Haskell será um grande bem para você!
Se você já esta lendo isto, existem boas chances de você querer aprender Haskell. Muito bem, você já esta no lugar certo, mas antes vamos conversar um pouco sobre este tutorial.
Bem-vindo ao <strong>Aprender Haskell será um grande bem para você</strong>! Se você está lendo isto, existem boas chances de você querer aprender Haskell. Muito bem, você já está no lugar certo, mas antes vamos conversar um pouco sobre este tutorial.

Eu decidi escrever porque estava querendo solidificar meus conhecimentos em Haskell e porque pensei que poderia ajudar as pessoas novas em Haskell a aprende-lo sob a minha perspectiva. Este é só mais um tutorial sobre Haskell pairando pela internet. Quando eu comecei em Haskell eu não aprendi a partir de apenas uma fonte. O meu caminho para o aprendizado passou pela leitura de diversos e diferentes tutoriais e artigos porque cada um explicava algo seguindo por um caminho diferente do outro. Ao passar por diferentes fontes, eu consegui juntar as peças e tudo acabou caindo no mesmo lugar. Portanto, esta é apenas mais uma fonte adicional a se utilizar para aprender Haskell para que você tenha uma maior chance de encontrar uma que você realmente goste.
Decidi escrever porque estava querendo solidificar meus conhecimentos em Haskell e porque pensei que poderia ajudar as pessoas novas em Haskell a aprende-lo sob a minha perspectiva. Este é só mais um tutorial sobre Haskell pairando pela Internet. Quando comecei a programar Haskell, não aprendi a partir de uma única fonte. O meu caminho para o aprendizado passou pela leitura de diversos tutoriais e artigos diferentes, porque cada um explicava algo seguindo por um caminho diferente do outro. Ao passar por diferentes fontes, consegui juntar as peças e tudo acabou caindo no mesmo lugar. Portanto, este tutorial é apenas mais uma fonte adicional para aprender Haskell, assim você pode ter mais chance de encontrar uma leitura que te agrade.

Este tutorial é destinado a pessoas que tenham experiência em linguagens de programação imperativa (C, C++, Java, Python &hellip;) sem terem programado antes em uma linguagem funcional (Haskell, ML, OCaml &hellip;). Apesar de que eu aposto que se você não tiver uma larga experiência em programação, um rápido capítulo como o que você irá acompanhar vai habilitá-lo a aprender Haskell.
Este tutorial é destinado as pessoas que tenham experiência em linguagens de programação imperativa (C, C++, Java, Python &hellip;) sem terem programado antes em uma linguagem funcional (Haskell, ML, OCaml &hellip;). No entanto, aposto que se você não tiver uma larga experiência em programação, um rápido capítulo, como o que ver a seguir, permitirá que você aprenda Haskell.

O canal #haskell (ou #haskell-br) na rede freenode é um belo local para mandar alguma questão caso você estiver emperrado. As pessoas são extremamente legais, pacienciosas e entendem os newbies.
O canal #haskell (ou #haskell-br) na rede freenode é um bom local para mandar alguma questão se você estiver com alguma dificuldade. As pessoas do canal são extremamente atenciosas, pacientes e entendem os newbies.

Eu falhei aproximadamente 2 vezes antes de finalmente aprender Haskell, isto porque tudo me parecia muito estranho e eu não conseguia entender.
Mas logo em seguida, após ultrapassar essa primeira barreira, me veio o "estalo" e então entendi que era tudo muito fácil. Acho que o que estou tentando dizer é o seguinte: Haskell é muito legal e se você realmente tiver interesse em programação você deve continuar mesmo que ele lhe pareça estranho. Aprender Haskell é muito parecido com quando se está aprendendo a programar pela primeira vez &mdash; isto que é divertido! Ele te força a pensar diferente, o que nos remete ao próximo capítulo &hellip;
Falhei duas vezes antes de finalmente aprender Haskell, isto porque tudo me parecia muito estranho e não conseguia entender.
Mas logo em seguida, após ultrapassar essa primeira barreira, me veio um "estalo", e então entendi que era tudo muito fácil. Acho que o que estou tentando dizer é o seguinte: Haskell é muito legal e se você realmente tiver interesse em programação, você deve continuar mesmo que ele lhe pareça estranho. Aprender Haskell é muito parecido com quando se está aprendendo a programar pela primeira vez &mdash; isto que é divertido! Ele te força a pensar diferente, o que nos remete ao próximo capítulo &hellip;
11 changes: 5 additions & 6 deletions cap01-introducao/cap01-part02.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
Então, o que é Haskell?
=======================

Haskell é uma linguagem de programação puramente funcional.
Em linguagens de programação imperativas você pensa nas coisas seguindo uma sequência computacional de tarefas sendo executadas, embora durante o processo possam mudar de estado. Por exemplo, você define uma variável como 5 e então faz alguma coisa e em seguida a define como sendo alguma outra coisa qualquer. Você possui o controle do fluxo da estrutura podendo fazer uma determinada ação diversas vezes. Na programação puramente funcional você não diz para o computador o que fazer, porém muitas vezes você diz em qual coisa está. O fatorial de um número é o produto de todos os números sobre 1 deste número, a soma de uma lista de números é o primeiro mais a soma de todos os outros números e assim por diante. Você expressa isto na forma de funções. Você também não pode definir uma variável como sendo alguma coisa e em seguida defini-lá como sendo alguma outra coisa mais tarde. Se você disser a uma função que algo é 5, você não poderá dizer depois que é alguma outra coisa porque você já disse que era 5. O que você é? Algum tipo de mentiroso? Então, em linguagens puramente funcionais, uma função não tem efeitos colaterais. A única coisa que podemos fazer com uma função é calcular algo e devolvê-lo como um resultado. Inicialmente, eu vi isto como uma limitação, porém isto realmente tem algumas consequências interessantes: se a função é chamada duas vezes com os mesmos parâmetros, isto garantirá o retorno de um mesmo resultado. Isso se chama <strong>transparência referencial</strong> e não só permite que o compilador raciocine sobre o comportamento do programa, como também permite que você deduza facilmente (e até mesmo prove) que uma função está correta e, em seguida, construa funções mais complexas juntando diversas funções simples por "colagem".
Haskell é uma <strong>linguagem de programação puramente funcional</strong>. Em linguagens de programação imperativas, você pensa nas coisas seguindo uma sequência computacional de tarefas sendo executadas, embora durante o processo possam mudar de estado. Por exemplo, ao definir uma variável com o valor 5, após isso faz alguma coisa, e em seguida define esta variável como sendo alguma outra coisa qualquer. Você possui o controle do fluxo da estrutura podendo fazer uma determinada ação diversas vezes. Na programação puramente funcional você não diz para o computador o que fazer, porém muitas vezes você diz em qual coisa está. O fatorial de um número é o produto de todos os números sobre 1 deste número; a soma de uma lista de números é o primeiro mais a soma de todos os outros números; e assim por diante. Você expressa isto na forma de funções. Você também não pode definir uma variável como sendo de um tipo e em seguida defini-lá como sendo alguma outra. Se você disser a uma função que algo é 5, você não poderá dizer depois que é outra coisa, porque você já disse que era 5. O que você é? Algum tipo de mentiroso? Então, em linguagens puramente funcionais, uma função não tem efeitos colaterais. A única coisa que podemos fazer com uma função é calcular algo e devolvê-lo como um resultado. Inicialmente, vi isto como uma limitação, porém isto realmente tem algumas consequências interessantes: se a função é chamada duas vezes com os mesmos parâmetros, isto garantirá o retorno de um mesmo resultado. Isso se chama <strong>transparência referencial</strong> e não só permite que o compilador raciocine sobre o comportamento do programa, como também permite que você deduza facilmente (e até mesmo prove) que uma função está correta e, em seguida, construa funções mais complexas juntando diversas funções simples por "colagem".


Haskell é preguiçoso. Isso significa que a menos que seja especificamente dito de outra forma, Haskell não irá executar funções e calcular as coisas antes que ele seja realmente obrigado a lhe mostrar um resultado. Isto vai bem de encontro com a transparência referencial que lhe permite pensar em programas como uma série de transformações nos dados. Isto também permite simplificar coisas como estruturas de dados infinitas. Digamos que você tem uma lista de números imutáveis [code] xs = [1,2,3,4,5,6,7,8] [/ code] e uma função [code] doubleMe [/ code] que multiplica cada elemento por 2 e em seguida retorna uma nova lista. Caso quiséssemos multiplicar nossa lista por 8 em uma linguagem imperativa fazendo [code] doubleMe (doubleMe (doubleMe (xs ))) [/ code], ele provavelmente iria passar uma vez pela lista, fazer uma cópia e retornar. Em seguida, ele iria passar por mais duas vezes e retornar o resultado. Em uma linguagem preguiçosa, chamando [code] doubleMe [/ code] numa lista sem forçar para que seja mostrado algum resultado assim que acabar, ela irá lhe dizer "Sim sim, faço isso mais tarde". Mas uma vez que você queira ver o resultado, o primeiro [code] doubleMe [/ code] dirá para o segundo que quer o resultado do 1, agora! O segundo 1 irá dizer para o terceiro 1 e o terceiro 1 relutantemente irá retornar o 1 duplicado, com um 2. O segundo 1 recebido irá retornar um 4 para o primeiro. O primeiro 1 olhará aquilo e dirá para você que o primeiro elemento é 8. Por isso, ele só passa uma vez pela lista e só quando você realmente precisa dela. Dessa maneira, quando você quiser alguma coisa em uma linguagem "preguiçosa", você poderá ter apenas alguns dados iniciais e eficientemente transformá-los e melhorá-los para que eles se assemelhem com aquilo que você quer no final.
Haskell é <strong>preguiçoso</strong>. Isso significa que a menos que seja especificamente dito de outra forma, o Haskell não irá executar as funções e calcular as coisas antes que ele seja realmente obrigado a lhe mostrar um resultado. Isto vai bem de encontro com a transparência referencial, pois lhe permite pensar em programas como uma série de <strong>transformações nos dados</strong>. Isto também permite simplificar coisas como estruturas de dados infinitas. Digamos que você tem uma lista de números imutáveis [code] xs = [1,2,3,4,5,6,7,8] [/ code] e uma função [code] dobro [/ code] que multiplica cada elemento por 2 e em seguida retorna uma nova lista. Caso quiséssemos multiplicar nossa lista por 8, em uma linguagem imperativa fazendo [code] dobro (dobro (dobro (xs))) [/ code], ele provavelmente passaria uma vez pela lista, fazendo uma cópia e retornando. Em seguida, ele passaria por mais duas vezes e retornaria o resultado. Em uma linguagem preguiçosa, chamando [code] dobro [/ code] numa lista sem forçar que seja mostrado algum resultado assim que acabar, ela irá lhe dizer "Sim sim, faço isso mais tarde". Mas uma vez que você queira ver o resultado, o primeiro [code] dobro [/ code] dirá para o segundo que quer o resultado do 1, agora! O segundo 1 dirá para o terceiro 1 e o terceiro 1 relutantemente retornará o 1 duplicado, com um 2. O segundo 1 recebido retornará um 4 para o primeiro. O primeiro 1 olhará aquilo e dirá para você que o primeiro elemento é 8. Por isso, ele só passa uma vez pela lista e só quando realmente for necessário. Dessa maneira, quando você quiser alguma coisa de uma linguagem "preguiçosa", você poderá ter apenas alguns dados iniciais e eficientemente transformá-los e melhorá-los para que se assemelhem com aquilo que você quer no final.

Haskell é estaticamente tipado. Quando você compilar seu programa, o compilador saberá quais partes do código é um número, o que é uma string e assim por diante. Isso significa que uma série de possíveis erros poderão ser capturados em tempo de compilação. Se você tentar adicionar um número a uma string, o compilador irá se queixar de você. Haskell usa um bom sistema de tipos que tem inferência de tipo. Isso significa que você não precisa explicitamente identificar cada pedaço de código com um tipo porque o sistema de tipos inteligente descobrirá muito sobre ele. Se você disser [code] a = 5 + 4 [/ code], você não precisará dizer para o Haskell que [código] a [/ code] é um número, ele irá descobrir isso por si só. Inferência de tipo também permite que o seu código seja mais genérico. Se você fizer uma função de soma com dois parâmetros e não declarar explicitamente seus tipos, ela irá funcionar com quaisquer valores que sejam números.
Haskell é <strong>estaticamente tipado</strong>. Quando você compilar seu programa, o compilador saberá quais partes do código é um número, o que é uma string e assim por diante. Isso significa que uma série de possíveis erros poderão ser identificados em tempo de compilação. Se você tentar adicionar um número a uma string, o compilador irá reclamar. Haskell usa um bom sistema de tipos que tem inferência de tipo. Isso significa que você não precisa explicitamente identificar cada pedaço de código com um tipo, porque o sistema de tipos inteligente descobrirá muito sobre ele. Se disser que [code] a = 5 + 4 [/ code], você não precisará dizer para o Haskell que [código] a [/ code] é um número, ele descobrirá isso por si só. Inferência de tipo também permite que o seu código seja mais genérico. Se fizer uma função de soma com dois parâmetros e não declarar explicitamente seus tipos, ela funcionará com quaisquer valores que sejam números.

Haskell é <em> elegante e conciso </ em>. Isto porque ele utiliza uma série de conceitos de alto nível, programas Haskell são normalmente mais curtos do que os seus equivalentes imperativos. E programas mais curtos são mais fáceis de se manter e têm menos bugs.
Haskell é <strong>elegante e conciso</strong>. Isto porque utiliza uma série de conceitos de alto nível, programas Haskell são normalmente mais curtos do que os seus equivalentes imperativos. E programas mais curtos são mais fáceis de se manter e têm menos bugs.

Haskell foi feito por caras realmente inteligentes (com doutorado). O trabalho sobre Haskell começou em 1987 quando uma comissão de pesquisadores se reuniu para projetar uma linguagem matadora. Em 2003, o Relatório Haskell foi publicado já com uma versão estável da linguagem.
Haskell foi feito por <strong>caras realmente inteligentes</strong> (com doutorado). O trabalho sobre Haskell começou em 1987 quando uma comissão de pesquisadores se reuniu para projetar uma linguagem matadora. Em 2003, o Relatório Haskell foi publicado já com uma versão estável da linguagem.
8 changes: 4 additions & 4 deletions cap01-introducao/cap01-part03.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
O que eu preciso para embarcar nessa
====================================
O que preciso para embarcar nessa?
==================================

Um editor de texto e um compilador Haskell. Provavelmente você já tem um editor de texto favorito instalado, então não perca tempo com isso. Neste tutorial iremos usar o <a href="https://www.haskell.org/ghc/" target="_blank">GHC</a>, o compilador Haskell mais usado. O melhor modo de iniciar na linguagem é baixando o <a href="http://hackage.haskell.org/platform/">Haskell Platform</a>, que é algo como o Haskell com esteróides.
Um editor de texto e um compilador Haskell. Provavelmente você já tem um editor de texto favorito instalado, então não perca tempo com isso. Neste tutorial usaremos o <a href="https://www.haskell.org/ghc/" target="_blank">GHC</a>, o compilador Haskell mais usado. O melhor modo de iniciar na linguagem é baixando o <a href="http://hackage.haskell.org/platform/">Haskell Platform</a>, que é algo como o Haskell com esteróides.

GHC pode pegar um script Haskell (que normalmente tem uma extensão .hs) e compilá-lo, mas ainda existe um modo interativo que permite que você interativamente interaja com os scripts. Interativamente. Você pode chamar funções de scripts carregados que os resultados serão exibidos imediatamente. Para o seu aprendizado é muito mais fácil e rápido que compilar toda vez que fizer uma alteração e enfim executar o programa a partir do prompt. O modo interativo é chamado digitando <span class="fixed"> ghci </ span> no seu prompt. Se você definir algumas funções em um arquivo chamado, digamos, [code] myfunctions.hs [/ code], você poderá carregar essas funções digitando [code]: l myfunctions [/ code] para então poder brincar com elas, desde que [code] myfunctions.hs [/ code] esteja na mesma pasta na qual o [code] ghci[/ code] foi invocado. Se você mudar o seu script ".hs", basta executar [code]: l myfunctions [/ code] novamente ou fazer [code] : r[/ code], que é o equivalente a recarregar o script atual. O processo comum para mim quando estou brincando, é definir algumas funções em um arquivo .hs, carregá-lo e modificá-lo sem pudor. Quando preciso, carrego um outro arquivo .hs novamente e assim por diante. Isto é também o que faremos aqui.
O GHC pega um script Haskell (que normalmente tem uma extensão .hs) e compila, mas ainda existe um modo interativo que permite interação com os scripts. Interativamente você pode chamar as funções dos scripts carregados e ver os resultados imediatamente. Para o seu aprendizado é muito mais fácil e rápido ver interativamente, do que compilar toda vez que fizer uma alteração para depois executar o programa a partir do prompt. O modo interativo é chamado digitando <span class="fixed">ghci</span> no seu prompt. Se você definir algumas funções em um arquivo chamado, digamos, [code] minhasfuncoes.hs [/ code], você poderá carregar essas funções digitando [code]: l minhasfuncoes [/ code] para então poder brincar com elas, desde que [code] minhasfuncoes.hs [/ code] esteja na mesma pasta na qual o [code] ghci [/ code] foi invocado. Se você mudar o seu script ".hs", basta executar [code]: l minhasfuncoes [/ code] novamente ou fazer [code] : r[/ code], que é o equivalente a recarregar o script atual. O processo comum para mim quando estou brincando, é definir algumas funções em um arquivo .hs, carregá-lo e modificá-lo sem pudor. Quando preciso, carrego um outro arquivo .hs novamente e assim por diante. Isto é também o que faremos aqui.
Loading