Introdução ao Haskell


755

Por alguns dias, tentei entender o paradigma de programação funcional em Haskell. Eu fiz isso lendo tutoriais e assistindo screencasts, mas nada realmente parece grudar. Agora, ao aprender várias linguagens imperativas / OO (como C, Java, PHP), os exercícios têm sido um bom caminho para eu seguir. Mas como eu realmente não sei do que Haskell é capaz e porque existem muitos conceitos novos para utilizar, não sei por onde começar.

Então, como você aprendeu Haskell? O que fez você realmente "quebrar o gelo"? Além disso, algumas boas idéias para o início dos exercícios?


Respostas:


2476

Vou ordenar este guia pelo nível de habilidade que você tem em Haskell, passando de um iniciante a um especialista. Observe que esse processo levará muitos meses (anos?), Portanto é bastante longo.

Principiante Absoluto

Em primeiro lugar, Haskell é capaz de qualquer coisa, com habilidade suficiente. É muito rápido (atrás apenas de C e C ++ na minha experiência) e pode ser usado para qualquer coisa, desde simulações a servidores, guis e aplicativos da web.

No entanto, existem alguns problemas que são mais fáceis de escrever para um iniciante em Haskell do que outros. Problemas matemáticos e programas de processos de lista são bons candidatos para isso, pois exigem apenas o conhecimento mais básico de Haskell para poder escrever.

Em primeiro lugar, alguns bons guias para aprender o básico do Haskell são o tutorial feliz aprender haskell e os 6 primeiros capítulos de aprender um haskell . Ao ler estes, é uma boa idéia também resolver problemas simples com o que você conhece.

Outros dois bons recursos são a Programação Haskell desde os primeiros princípios e a Programação em Haskell . Os dois vêm com exercícios para cada capítulo, para que você tenha pequenos problemas simples que correspondem ao que aprendeu nas últimas páginas.

Uma boa lista de problemas para tentar é a página de problemas do haskell 99 . Eles começam muito básicos e ficam mais difíceis à medida que avança. É uma prática muito boa fazer muitas delas, pois elas permitem que você pratique suas habilidades nas funções de recursão e ordem superior. Eu recomendaria ignorar quaisquer problemas que exijam aleatoriedade, pois isso é um pouco mais difícil em Haskell. Verifique esta questão de SO caso queira testar suas soluções com o QuickCheck (consulte Intermediário abaixo).

Depois de ter feito alguns deles, você pode passar a resolver alguns dos problemas do Project Euler . Eles são classificados por quantas pessoas os concluíram, o que é uma boa indicação de dificuldade. Eles testam sua lógica e Haskell mais do que os problemas anteriores, mas você ainda deve conseguir fazer os primeiros. Uma grande vantagem que Haskell tem com esses problemas é que os números inteiros não são limitados em tamanho. Para concluir alguns desses problemas, será útil ler os capítulos 7 e 8 de aprender um Haskell também.

Principiante

Depois disso, você deve ter um bom conhecimento das funções de recursão e ordem superior, por isso seria um bom momento para começar a resolver alguns problemas do mundo real. Um bom lugar para começar é o Mundo Real Haskell (livro on-line, você também pode comprar uma cópia impressa). Eu achei os primeiros capítulos introduzidos muito rapidamente para alguém que nunca havia feito programação funcional / usado recursão antes. No entanto, com a prática que você teria de resolver os problemas anteriores, você deve achar perfeitamente compreensível.

Trabalhar com os problemas do livro é uma ótima maneira de aprender a gerenciar abstrações e criar componentes reutilizáveis ​​no Haskell. Isso é vital para as pessoas acostumadas à programação orientada a objetos (oo), pois os métodos normais de abstração oo (classes oo) não aparecem no Haskell (Haskell possui classes de tipo, mas são muito diferentes das classes oo, mais como interfaces oo ) Não acho que seja uma boa idéia pular capítulos, pois cada um deles apresenta muitas novas idéias usadas nos capítulos posteriores.

Depois de um tempo, você chegará ao capítulo 14, o temido capítulo das mônadas (dum dum dummmm). Quase todo mundo que aprende Haskell tem problemas para entender as mônadas, devido ao quão abstrato o conceito é. Não consigo pensar em nenhum conceito em outra linguagem que seja tão abstrato quanto as mônadas na programação funcional. Mônadas permite que muitas idéias (como operações de E / S, cálculos que possam falhar, análise, ...) sejam unificadas sob uma idéia. Portanto, não desanime se, depois de ler o capítulo das mônadas, você realmente não as entender. Achei útil ler muitas explicações diferentes das mônadas; cada um dá uma nova perspectiva sobre o problema. Aqui está uma lista muito boa de tutoriais de mônada . Eu recomendo o All About Monads , mas os outros também são bons.

Além disso, leva um tempo para que os conceitos sejam realmente absorvidos. Isso ocorre pelo uso, mas também pelo tempo. Acho que às vezes dormir com um problema ajuda mais do que qualquer outra coisa! Eventualmente, a idéia clicará e você se perguntará por que lutou para entender um conceito que, na realidade, é incrivelmente simples. É incrível quando isso acontece, e quando acontece, você pode achar que Haskell é sua linguagem de programação imperativa favorita :)

Para ter certeza de que você está entendendo perfeitamente o sistema do tipo Haskell, tente resolver 20 exercícios intermediários do haskell . Esses exercícios usam nomes divertidos de funções como "furry" e "banana" e ajudam você a entender bem alguns conceitos básicos de programação funcional, se ainda não os tiver. Ótima maneira de passar a noite com um monte de papéis cobertos por flechas, unicórnios, salsichas e bananas peludas.

Intermediário

Depois de entender o Monads, acho que você fez a transição de um programador iniciante em Haskell para um intermediário. Então, para onde ir a partir daqui? A primeira coisa que eu recomendaria (se você ainda não os aprendeu aprendendo mônadas) são os vários tipos de mônadas, como Reader, Writer e State. Mais uma vez, o mundo real Haskell e Tudo sobre as mônadas oferecem uma ótima cobertura disso. Para concluir seu treinamento em mônada, é essencial aprender sobre os transformadores de mônada. Isso permite combinar diferentes tipos de mônadas (como uma mônada do Reader e do Estado) em uma. Isso pode parecer inútil para começar, mas depois de usá-los por um tempo, você se perguntará como viveu sem eles.

Agora você pode terminar o livro Haskell do mundo real, se quiser. Ignorar capítulos agora realmente não importa, desde que você tenha mônadas. Basta escolher o que você está interessado.

Com o conhecimento que você teria agora, você poderá usar a maioria dos pacotes no cabal (pelo menos os documentados ...), bem como a maioria das bibliotecas que acompanham o Haskell. Uma lista de bibliotecas interessantes para tentar seria:

  • Parsec : para analisar programas e texto. Muito melhor do que usar regexps. Excelente documentação, também possui um capítulo Haskell do mundo real.

  • QuickCheck : Um programa de teste muito legal. O que você faz é escrever um predicado que sempre deve ser verdadeiro (por exemplo length (reverse lst) == length lst). Em seguida, você passa o predicado ao QuickCheck e ele gera muitos valores aleatórios (nesse caso, lista) e testa se o predicado é verdadeiro para todos os resultados. Veja também o manual online .

  • HUnit : teste de unidade em Haskell.

  • gtk2hs : A estrutura gui mais popular do Haskell, permite escrever aplicativos gtk no Haskell.

  • happstack : Uma estrutura de desenvolvimento web para Haskell. Não usa bancos de dados, mas um armazenamento de tipo de dados. Documentos muito bons (outros frameworks populares seriam snap e yesod ).

Além disso, existem muitos conceitos (como o conceito Mônada) que você deve aprender eventualmente. Isso será mais fácil do que aprender mônadas pela primeira vez, pois seu cérebro estará acostumado a lidar com o nível de abstração envolvido. Uma visão geral muito boa para aprender sobre esses conceitos de alto nível e como eles se encaixam é a Typeclassopedia .

  • Aplicável: Uma interface como Mônadas, mas menos poderosa. Toda mônada é aplicável, mas não vice-versa. Isso é útil, pois existem alguns tipos que são aplicáveis, mas não são mônadas. Além disso, o código gravado usando as funções Aplicativas é geralmente mais fácil de compor do que escrever o código equivalente usando as funções Monad. Consulte Functors, Functors Aplicáveis ​​e Monoids no guia aprender um haskell.

  • Dobrável , Traversable : Typeclasses que abstraem muitas das operações de listas, para que as mesmas funções possam ser aplicadas a outros tipos de contêineres. Veja também a explicação do wiki haskell .

  • Monóide : Um Monóide é um tipo que tem um valor zero (ou mempty) e uma operação notada <>que une dois Monoids, como aquele x <> mempty = mempty <> x = xe x <> (y <> z) = (x <> y) <> z. Essas são chamadas leis de identidade e associatividade. Muitos tipos são monoides, como números, com mempty = 0e <> = +. Isso é útil em muitas situações.

  • Setas : as setas são uma maneira de representar cálculos que recebem uma entrada e retornam uma saída. Uma função é o tipo mais básico de seta, mas existem muitos outros tipos. A biblioteca também possui muitas funções muito úteis para manipular setas - elas são muito úteis mesmo se usadas apenas com funções Haskell antigas e simples.

  • Matrizes : as várias matrizes mutáveis ​​/ imutáveis ​​em Haskell.

  • Mônada ST : permite escrever código com um estado mutável que é executado muito rapidamente, enquanto permanece puro fora da mônada. Veja o link para mais detalhes.

  • FRP: Programação Reativa Funcional, uma nova maneira experimental de escrever código que lida com eventos, gatilhos, entradas e saídas (como uma GUI). Eu não sei muito sobre isso embora. A palestra de Paul Hudak sobre yampa é um bom começo.

Há muitos novos recursos de idioma que você deve dar uma olhada. Vou apenas listá-los, você pode encontrar muitas informações sobre eles no google, no haskell wikibook , no site haskellwiki.org e na documentação do ghc .

  • Classes do tipo multiparâmetros / dependências funcionais
  • Famílias de tipos
  • Tipos quantificados existencialmente
  • Tipos fantasmas
  • GADTS
  • outras...

Um monte de Haskell é baseado em teoria de categorias , então você pode querer investigar isso. Um bom ponto de partida é a Teoria das Categorias para Cientistas da Computação . Se você não quiser comprar o livro, o artigo relacionado ao autor também é excelente.

Finalmente, você vai querer aprender mais sobre as várias ferramentas Haskell. Esses incluem:

  • ghc (e todos os seus recursos)
  • cabal : o sistema de pacotes Haskell
  • darcs : um sistema de controle de versão distribuído escrito em Haskell, muito popular para programas Haskell.
  • haddock : um gerador automático de documentação Haskell

Ao aprender todas essas novas bibliotecas e conceitos, é muito útil escrever um projeto de tamanho moderado em Haskell. Pode ser qualquer coisa (por exemplo, um pequeno jogo, analisador de dados, site, compilador ). Trabalhar nisso permitirá que você aplique muitas das coisas que está aprendendo agora. Você fica nesse nível por muito tempo (é onde eu estou).

Especialista

Você levará anos para chegar a esse estágio (olá a partir de 2009!), Mas a partir daqui, acho que você começa a escrever artigos em phd, novas extensões de ghc e novas abstrações.

Conseguindo ajuda

Finalmente, em qualquer estágio do aprendizado, há vários locais para obter informações. Esses são:

  • o canal #haskell irc
  • as listas de discussão . Vale a pena se inscrever apenas para ler as discussões que ocorrem - algumas são muito interessantes.
  • outros locais listados na página inicial haskell.org

Conclusão

Bem, isso acabou por mais tempo do que eu esperava ... De qualquer forma, acho que é uma idéia muito boa se tornar proficiente em Haskell. Leva muito tempo, mas isso ocorre principalmente porque você está aprendendo uma maneira completamente nova de pensar. Não é como aprender Ruby depois de aprender Java, mas como aprender Java depois de aprender C. Além disso, estou descobrindo que minhas habilidades de programação orientada a objetos melhoraram como resultado do aprendizado de Haskell, pois estou vendo muitas novas maneiras de abstrair idéias.


35
Yay flechas! Primeiro, você deixa as mônadas moldarem seu cérebro, depois fica de cabeça e pensa em comônadas, e depois faz as duas coisas ao mesmo tempo para obter flechas :) Há um poder expressivo em Haskell que pode ser aberto com o nível de tipo programação também.
519 ephemient

13
O @nanothief Monadé mais poderoso, mas também menos composicional ... muitas pessoas usam mônadas onde poderiam ter conseguido um Applicativecódigo mais limpo . A maioria das coisas que são Functors também são Monads, mas você não usa >>=e returnquando fmapé suficiente, porque o último leva a um código muito mais simples, se você pode usá-lo.
Tom Crockett

8
@pelotom, adicionei o link typeclassopedia, além de melhores razões para usar o aplicativo nessa seção e removi a seção Functor. É difícil obter os conceitos de Mônada e Aplicável na ordem certa, devido à ênfase nas Mônadas na maioria dos materiais didáticos (incluindo a RWH). Por outro lado, o tutorial para ensinar um haskell percorreu um longo caminho desde que eu escrevi a resposta inicialmente (quase 2 anos: O) e ensina o Applicative antes da Monad, talvez essa seja agora a maneira recomendada de aprender o haskell.
David Miani

2
Ótimo conselho. Comecei isso há mais de um ano e estou na maior parte do estágio intermediário. Feedback: o capítulo da mônada do RWH (capítulo 14) é pouco explicado. A leitura da versão on-line do RWH é benéfica, pois contém comentários de crowdsourcing que ajudam o capítulo. O FWIW, você poderia ter inventado as mônadas , foi o tutorial da mônada que funcionou melhor para mim.
Tom

6
@ Tomf: Obrigado! Sempre me surpreendi com o desempenho dessa resposta - já faz quase cinco anos desde que a escrevi, mas ainda está forte. Porém, precisarei fazer uma atualização em breve, pois está um pouco desatualizada. Ele não menciona lentes, tubos, tipos de restrições, a plataforma haskell, números de nível de tipo e são tópicos novos muito importantes desde que isso foi escrito. Você está certo de que o RWH não é mais tão bom, não é atualizado há muito tempo e muitos exemplos não estão sendo compilados. Ainda bem que ainda foi útil para você.
David Miani

180

Algum colega meu teve uma boa experiência com Learn You a Haskell for Great Good! .

Tutorial voltado para pessoas que têm experiência em linguagens de programação imperativas, mas que nunca programaram em uma linguagem funcional antes.

E verifique as respostas aqui também


27
Eu segundo isso. Além disso, como não é óbvio, aqui está um link para uma versão em PDF para download do tutorial: learnyouahaskell.com/learnyouahaskell.pdf O design da web é ótimo, mas eu também gosto de ter uma cópia para o metrô.
Telêmaco

8
Comecei com isso, mas minha opinião é que você deveria ir diretamente para o mundo real Haskell. A diferença é como aprender C com K&R ou "C para manequins", que tenta ser simples, mas perde coisas importantes com sua abordagem. Acho melhor esclarecer os fatos, em vez de tentar aprender Haskell "da maneira imperativa".
31410 John Smith

7
Eu absolutamente amo isso, e investi muito tempo nisso e no mundo real Haskell. A IMO, "Aprenda um Haskell", fornece uma visão mais profunda do que o Mundo Real Haskell, embora ambos sejam ótimos recursos.
Charlie Flowers

7
@ abababa22 Acho que ler LYAH primeiro e depois ir para RWH é a melhor ideia. LYAH não ensina apenas Haskell; ensina programação funcional. Você começa a pensar de maneira funcional quando resolve problemas. Claramente, apenas o LYAH não seria suficiente para escrever um aplicativo grande, mas isso inclina sua mente da maneira certa. Se você é de formação imperativa, esta é a melhor maneira, IMO
Abdulsattar Mohammed

4
@Telemachus Apenas para observar: o PDF não é a versão final, pelo menos está faltando o último capítulo.
Sdcvvc

103

Aqui está um bom livro que você pode ler on-line: Mundo Real Haskell

A maioria dos programas de Haskell que fiz foi para resolver problemas do Project Euler .

Uma vez que um conselho que li há pouco tempo atrás, era que você deveria ter um conjunto padrão de problemas simples que sabe resolver (em teoria) e, sempre que tenta aprender um novo idioma, implementa esses problemas nesse idioma.


2
Na minha experiência, Haskell do mundo real é ótimo, até você chegar ao capítulo 5. A partir de então, eu não o recomendaria.
MasterMastic

Por que @MasterMastic? Qual é o problema além do capítulo 5? Eu gostaria de saber antes de gastar o dinheiro.
Jay Blanchard

@ JayBlanchard No capítulo 5, você começa a obter um exemplo concreto de uma biblioteca, o que é legal, mas eles lhe dizem o que farão, faça-o, mas não explicam o porquê inteiramente, e não claramente, e há um pouco de literais hexadecimais mágicos. Você está apenas passando pelos movimentos. Esse não foi o maior problema para mim, o maior problema foi que o livro depende muito desse tipo de exemplos longos e duros (tempo suficiente para levar mais de um capítulo inteiro). Você mal consegue ler as partes que deseja. Eu acho ótimos autores, conhecimento incrível, mas execução extremamente ruim.
MasterMastic 5/05


69

Para adicionar respostas de outras pessoas - existe uma útil que o ajudará na codificação (por exemplo, na solução de problemas do projeto Euler): Hoogle . Você pode usar a interface da linha de comandos ou a interface da web .

Linha de comando

Depois de instalar a plataforma Haskell, certifique-se de cabal install hoogle

Exemplo de uso do Hoogle:

Você tem uma função f x = 3 * x + 1e deseja aplicá-la (5 :: Int), aplique-a no resultado e nesse resultado e assim por diante e obtenha uma lista infinita desses valores. Você suspeita que já exista uma função para ajudá-lo (não especificamente para o seu fpensamento).

Essa função seria do tipo (a -> a) -> a -> [a]se for necessária f 5ou a -> (a -> a) -> [a]se for necessária 5 f(assumimos que a função é para tipos gerais e não apenas Ints)

$ hoogle "a -> (a -> a) -> [a]"
Prelude iterate :: (a -> a) -> a -> [a]

Sim, a função que você precisa já existe e é chamada iterate. você usa por iterate func 5!

interface web

O resultado para o mesmo exemplo pode ser encontrado aqui .


Encontrar as funções padrão da biblioteca para o que você precisa fica muito mais fácil depois que você entende como pedir ao Hoogle o que você precisa.
Ankh-morpork 28/02

57

A programação de Graham Hutton em Haskell é concisa, razoavelmente completa, e seus anos de ensino a Haskell realmente mostram. É quase sempre o que eu recomendo que as pessoas comecem, independentemente de onde você vá a partir daí.

Em particular, o Capítulo 8 ("Analisadores Funcionais") fornece as bases reais de que você precisa para começar a lidar com mônadas, e acho que é de longe o melhor lugar para começar, seguido por Tudo Sobre Mônadas . (No entanto, com relação a esse capítulo, observe as erratas do site: você não pode usar o doformulário sem alguma ajuda especial. Você pode aprender sobre as classes tipográficas primeiro e resolver esse problema por conta própria.)

Isso raramente é enfatizado para iniciantes em Haskell, mas vale a pena aprender bastante cedo, não apenas sobre o uso de mônadas, mas sobre a construção de seus próprios. Não é difícil, e os personalizados podem simplificar várias tarefas.


5
Este é um livro totalmente subestimado (e resposta). O capítulo sobre analisadores funcionais, seguido de um capítulo sobre E / S, nenhum dos quais sequer menciona mônadas, realmente brilha como uma abordagem pedagógica elegante.
Michiakig


31

Sugiro ingressar no canal #haskell irc e fazer perguntas lá. Foi assim que eu aprendi Haskell. Se você passar pelo Mundo Real Haskell, como sugerido acima, as respostas em tempo real às suas perguntas ajudarão bastante. Muitas pessoas inteligentes no #haskell escrevem Haskell por diversão e por lucro, para que você receba muitas informações boas. Tente!


5
+1 - Para ficar claro: não aprenda apenas com o canal irc. No início, não entre e pergunte "Como escrevo um programa de haskell? Como adiciono números?"
alternativa

Além do irc freenode, também há uma discussão animada sobre haskell nos bate-papos do Discord.
truthadjustr


19

Além disso, posso recomendar o Yet Another Tutorial de Haskell como introdução.

Outro bom recurso de aprendizado (provavelmente no nível intermediário), que me ajudou muito e não foi mencionado nas outras respostas, até onde posso ver, é a Typeclassopedia de Brent Yorgey , que pode ser encontrada em The Monad Reader (Issue 13)

Está escrito em um estilo muito acessível e contém (entre muitas outras coisas), os seguintes conselhos introdutórios:

Existem duas chaves para a sabedoria de um especialista em hackers Haskell:

  1. Entenda os tipos.

  2. Obtenha uma intuição profunda para cada classe de tipo e seu relacionamento com outras classes de tipo, respaldada pela familiaridade com muitos exemplos.

O próprio Monad Reader é um tesouro absoluto para programadores funcionais (não apenas para programadores Haskell).


14

Tente escrever programas fáceis nele.

Você pode encontrar tarefas de exemplo em vários livros, provavelmente.

Eu não recomendaria aderir aos livros didáticos Haskell / FP, apenas tente fazer coisas simples com ele: cálculos, manipulações de strings, acesso a arquivos.

Depois que resolvi uma dúzia, quebrei o gelo :)

Depois disso, leia muito sobre conceitos avançados (Mônadas, Setas, E / S, estruturas de dados recursivas), porque o haskell é infinito e existem muitos deles.


14

Eu acho que perceber o recurso de Haskell por exemplos é a melhor maneira de começar acima de tudo.

http://en.wikipedia.org/wiki/Haskell_98_features

Aqui estão tipeclasses complicadas, incluindo mônadas e flechas

http://www.haskell.org/haskellwiki/Typeclassopedia

para problemas do mundo real e projetos maiores, lembre-se destas tags: GHC (compilador mais usado), Hackage (libraryDB), Cabal (sistema de construção), darcs (outro sistema de construção).

Um sistema integrado pode economizar seu tempo: http://hackage.haskell.org/platform/

o banco de dados do pacote para este sistema: http://hackage.haskell.org/

Wiki do compilador do GHC: http://www.haskell.org/haskellwiki/GHC

Depois de Haskell_98_features e Typeclassopedia, acho que você já pode encontrar e ler a documentação sobre eles

A propósito, você pode testar algumas extensões de idiomas do GHC, que podem fazer parte do padrão haskell no futuro.

esta é a minha melhor maneira de aprender haskell. Espero que possa ajudá-lo.


13

Sugiro que você comece lendo o tutorial do BONUS e depois lendo o Real World Haskell (online gratuitamente) . Participe do canal de IRC #Haskell, em irc.freenode.com , e faça perguntas. Essas pessoas são absolutamente amigáveis ​​para iniciantes e me ajudaram muito ao longo do tempo. Além disso, aqui no SO é um ótimo lugar para obter ajuda com coisas que você não pode entender! Tente não desanimar, uma vez que ele clica, sua mente fica soprada.

O tutorial do BONUS irá prepará-lo e prepará-lo para o passeio emocionante que o Mundo Real Haskell traz. Eu te desejo sorte!


12

Se você só tem experiência com linguagens imperativas / OO, sugiro usar uma linguagem funcional mais convencional como um trampolim. Haskell é realmente diferente e você precisa entender muitos conceitos diferentes para chegar a qualquer lugar. Sugiro abordar uma linguagem no estilo ML (como, por exemplo, F #) primeiro.


Elm pode ser o mais próximo, mais usefule e destas alternativas novato-friendly ...
Pedro Rolo

1
Não concordo em passar por uma rota temporária, como F #. Para mim, é como beber uma vodka que você precisa beber rapidamente. Mais doloroso assim, mas o prazer também está lá. Rotas temporárias, só me levam a mais confusão.
precisa saber é o seguinte

10

A primeira resposta é muito boa. Para chegar ao nível de especialista, você deve fazer um doutorado com alguns dos próprios especialistas.

Sugiro que você visite a página de Haskell: http://haskell.org . Lá você tem muito material e muitas referências às coisas mais atualizadas em Haskell, aprovadas pela comunidade Haskell.


2
Desculpe, mas usar o argumento de doutorado aqui é como dizer que você precisa ter uma faca de cozinha de US $ 300 para ser um bom chef. Mesmo Simon Peyton Jones - pai de Haskell - não tem doutorado. Prática e persistência é o que leva à experiência aqui e em qualquer outro campo.
Petras Purlys
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.