Um rápido Hello World com Haskell
Clerivaldo Junior
Posted on October 4, 2023
TLDR: O objetivo deste artigo é ser uma porta de entrada bem direto ao ponto, baseando-se na própria doc do Haskell, desde como configurar o ambiente de desenvolvimento até compilar e rodar seu primeiro código.
"Haskell é uma linguagem puramente funcional avançada. Um produto open source com mais de 20 anos de pesquisa de ponta, que permite um rápido desenvolvimento de programas robustos, concisos e corretos."
Haskell Wiki
1. Instalando
Instale o compilador ghc
usando o comando curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
no Terminal. O procedimento padrão é pressionar a tecla enter sempre que questionado até a instalação finalizar.
PS.: Geralmente ao instalar o ghc
, os pacotes necessários também são instalados, tornando o próximo passo desnecessário. Caso isso ocorra com sua instalação, simplesmente pule para o capítulo 2.
Após a instalação, abra uma nova janela/aba do Terminal e execute o comando ghcup tui
para começarmos a instalar os pacotes restantes.
Seguindo a própria documentação do Haskell, precisamos de 4 pacotes:
- GHC (Glasgow Haskell Compiler, a.k.a Compilador)
- HLS (Haskell Language Server)
- Cabal (Ferramenta para estruturar projetos Haskell, executá-los, definir dependências, etc)
- Stack (Alternativa para o Cabal)
Não há nenhum segredo sobre como instalar estes pacotes assim que a GUI for executada, basta navegar com as setas do teclado para escolher o pacote desejado, e instalar com
i
. Aconselho instalar os pacotes marcados comorecommended
.
2. Executando seu primeiro código
Com os pacotes instalados, estamos preparados para escrever nossos primeiros códigos em Haskell. Podemos usar ghci
para iniciar uma CLI e rodar nosso código diretamente do terminal:
☁ ~ ghci
GHCi, version 9.4.7: https://www.haskell.org/ghc/ :? for help
ghci> 6 + 3^2 * 4
42
Mas vamos usar o Vscode como IDE para escrever alguns arquivos. Vamos criar um arquivo com extensão .hs
. Para nosso simples "Hello world" precisamos escrever o seguinte:
main = do
putStrLn "Hello World!"
Podemos ver que é bem parecido com varias outras langs que conhecemos(não tô falando de você Java).
Agora vamos compilar nosso arquivo usando ghc nome-do-arquivo.hs
, isso irá nos gerar um executável para rodar nosso programa. Aqui meu arquivo se chama simplesmente hello-world
:
☁ ~ ghc hello-world.hs
[1 of 2] Compiling Main ( hello-world.hs, hello-world.o )
[2 of 2] Linking hello-world
Depois disso, basta rodar nosso executável:
☁ ~ ./hello-world
Hello World!
E tá feito o programinha! Vale lembrar que o arquivo foi criado e compilado na mesma pasta.
3. Entendendo o que foi escrito
Tá mas o que é o main = do
? É basicamente o ponto de entrada para a aplicação, necessário para um programa feito em Haskell. Fora de blocos iniciados com do
as quebras de linha não fazem efeito ou diferença. Ao executar o programa, é necessário que a sequência de eventos esteja bem definida, logo usamos do
para que dentro do seu bloco a quebra de linha seja 'respeitada' e assim definir as etapas do programa, isso deve ficar mais claro ao escrever um pouco mais de código.
Vamos adicionar mais uma linha, compilar e executar, deve rodar sem problema algum:
main = do
putStrLn "Hello World!"
putStrLn "Bye Bye World!"
Compilando e executando:
☁ ~ ./hello-world
Hello World!
Bye Bye World!
Agora vamos forçar um erro, podemos fazer isso de duas formas diferentes, desrespeitando a quebra de linha quando usando do
:
main = do
putStrLn "Hello World!" putStrLn "Bye Bye World!"
Ou removendo o do
main =
putStrLn "Hello World!"
putStrLn "Bye Bye World!"
Ao tentar compilar em ambos os casos temos o seguinte erro:
~ ghc hello-world.hs
[1 of 2] Compiling Main ( hello-world.hs, hello-world.o ) [Source file changed]
hello-world.hs:2:5: error:
• Couldn't match expected type: (String -> IO ()) -> String -> t
with actual type: IO ()
• The function ‘putStrLn’ is applied to three value arguments,
but its type ‘String -> IO ()’ has only one
In a stmt of a 'do' block:
putStrLn "Hello, World!" putStrLn "Second line of code"
In the expression:
do putStrLn "Hello, World!" putStrLn "Second line of code"
• Relevant bindings include main :: t (bound at hello-world.hs:1:1)
|
2 | putStrLn "Hello, World!" putStrLn "Second line of code"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Em resumo: nosso primeiro putStrLn
está tentando printar a linha "Hello, World!" putStrLn "Second line of code"
. Conseguimos corrigir isso sem o do
adicionando >>
no que seria o final da primeira linha:
main =
putStrLn "Hello World!" >>
putStrLn "Bye Bye World!"
Isso dará uma estrutura e ordenação para nosso código, o informando para rodar primeiro putStrLn "Hello World!"
e depois putStrLn "Bye Bye World!"
.
4. Dever de casa
Haskell é uma linguagem funcional, logo vale escrever diferentes funções e entender seus comportamentos.
Sugestão: Adicionar ainda mais linhas e criar suas próprias funções fora do bloco main
.
Posted on October 4, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.