Como construir a sua primeira aplicação com Elm — Parte 1

Matheus Lima
Jun 1, 2016 · 5 min read

No meu último post, Elm: Programação Funcional no Front-End do jeito certo, falei sobre as principais características e vantagens da linguagem mas (praticamente) sem mostrar código. Ou seja, dei ênfase no porquê e não no como.

Neste post irei focar no como e mostrar na prática o passo a passo para criar uma aplicação bem simples com Elm.


Introdução

Vamos construir uma aplicação bem simples, mas que demonstra diversos aspectos da linguagem: um contador.

Contador simples

Na documentação do Elm podemos ver um exemplo bem parecido.

Modularização

import Html

Dessa forma podemos invocar funções do módulo Html, dessa forma:

Html.text 'Olá'

Mas repetir o nome do módulo toda vez que formos invocar uma função dele pode ser cansativo. Podemos evitar essa repetição alterando o import, expondo as funções que estamos usando:

import Html exposing (text)text 'Olá'

Podemos também expor todas as funções de um módulo, sem precisar nomear cada uma delas:

import Html exposing (..)text 'Olá'

Com isso já temos a primeira linha da nossa aplicação:

import Html exposing (..)

Model

model = 0

Opcionalmente, podemos deixar explícita a tipagem do modelo, fazendo uma anotação de tipo (ou Type Annotation), dessa forma:

model: Int
model = 0

Se não fizermos a anotação de tipo, o compilador irá automaticamente inferir os tipos.

Com isso nossa aplicação, está assim:

import Html exposing (..)model: Int
model = 0

View

Para refrescar a memória, é isso que precisamos:

Ou seja, dois botões: um para incrementar e um para decrementar, e um elemento de texto com o valor do contador.

Podemos então implementar a função que irá representar a view dessa forma:

view model =
div []
[ button [] [ text "-" ]
, div [] [ text (toString model) ]
, button [] [ text "+" ]
]

O código acima pode parecer complicado, mas vamos desmitificá-lo passo a passo.

1. view model =
2. div []
3. [ button [] [ text "-" ]
4. , div [] [ text (toString model) ]
5. , button [] [ text "+" ]
6. ]

Na linha 1 (em negrito), estamos criando uma função chamada view, que recebe como parâmetro o nosso model.

Essa nova função view receberá uma div, que também é uma função:

1. view model =
2. div []
3. [ button [] [ text "-" ]
4. , div [] [ text (toString model) ]
5. , button [] [ text "+" ]
6. ]

A função div recebe dois parâmetros:
1. O primeiro é uma lista de atributos (id, class, style, etc), no nosso caso ela vai ficar vazia porque não precisamos de nenhum atributo.
2. E o segundo é uma lista de elementos filhos dessa div.

1. view model =
2. div []
3. [ button [] [ text "-" ]
4. , div [] [ text (toString model) ]
5. , button [] [ text "+" ]
6. ]

Os filhos da div (da linha 2) serão:
1. Um botão para decrementar o contador (linha 3)
2. Uma outra div com o valor do contador (linha 4)
3. Um botão para incrementar o contador (linha 5)

Como o nosso model é um Int, não podemos simplesmente usá-lo na função text, porque ela espera uma String como parâmetro. Por isso convertemos o valor do model de um Int para uma String:

1. view model =
2. div []
3. [ button [] [ text "-" ]
4. , div [] [ text (toString model) ]
5. , button [] [ text "+" ]
6. ]

Agora basta explicitarmos as anotações de tipo da view.
Se analisarmos a função view, verificamos que ela espera um model como parâmetro (que é simplesmente um Int) e retorna um Html como resultado.
Isso resultaria em:

view: Int -> Html
view model =
div []
[ button [] [ text "-" ]
, div [] [ text (toString model) ]
, button [] [ text "+" ]
]

Porém isso está incorreto por um pequeno detalhe:

view: Int -> Html Msg

Mais pra frente vamos entender esse Msg obscuro, mas quero que nesse momento você foque apenas que a view recebe o model e retorna um Html.

Portanto, nossa aplicação completa se encontra dessa maneira:

import Html exposing (..)
model: Int
model = 0
view: Int -> Html Msg
view model =
div []
[ button [] [ text "-" ]
, div [] [ text (toString model) ]
, button [] [ text "+" ]
]

Type Aliases

No nosso caso, podemos criar um Alias para o modelo dessa forma:

type alias Model = Int

Ou seja, em todos os lugares da nossa aplicação que estamos usando o Int para nos referir ao model, podemos agora usar o próprio Model. Facilitando muito a leitura, principalmente em aplicações grandes.

Atualizando então a aplicação, temos:

import Html exposing (..)
type alias Model = Intmodel: Model
model = 0
view: Model -> Html Msg
view model =
div []
[ button [] [ text "-" ]
, div [] [ text (toString model) ]
, button [] [ text "+" ]
]

Essa foi apenas a Parte 1.
Clique aqui para ler também a Parte 2.


Se você gostou do post não se esqueça de dar um ❤ aqui embaixo!
E se quiser receber de antemão mais posts como esse,
assine nossa newsletter.

Seja um apoiador, doe BitCoins: 1BGVKwjwQxkr3w1Md2X8WHAsyRjDjyJiPZ

JSCasts

Cursos:

Obrigado por ler! ❤

Matheus Lima

Written by

Desenvolvedor JavaScript. Criador do Redux Zero. Viciado em Netflix, café e na NFL. Vegetariano. ENTJ. http://matheuslima.com/