<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Clayton Fidelis</title>
    <description>The latest articles on DEV Community by Clayton Fidelis (@fidelisclayton).</description>
    <link>https://dev.to/fidelisclayton</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F13265%2F1dc2f975-c701-4806-8bf3-86d668924341.jpeg</url>
      <title>DEV Community: Clayton Fidelis</title>
      <link>https://dev.to/fidelisclayton</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fidelisclayton"/>
    <language>en</language>
    <item>
      <title>Elm na prática - Events, Pattern Matching, Maybe, Dict e implementando a lógica do conversor</title>
      <dc:creator>Clayton Fidelis</dc:creator>
      <pubDate>Tue, 03 Mar 2020 16:30:44 +0000</pubDate>
      <link>https://dev.to/fidelisclayton/elm-na-pratica-events-pattern-matching-maybe-dict-e-implementando-a-logica-do-conversor-3p9f</link>
      <guid>https://dev.to/fidelisclayton/elm-na-pratica-events-pattern-matching-maybe-dict-e-implementando-a-logica-do-conversor-3p9f</guid>
      <description>&lt;p&gt;Chegamos na terceira parte dessa série de tutoriais sobre Elm, e hoje finalmente vamos implementar a lógica da nossa aplicação. O código dos tutoriais anteriores está disponível nesse link: &lt;a href="https://ellie-app.com/88hXjYRzqbwa1"&gt;https://ellie-app.com/88hXjYRzqbwa1&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parte 1&lt;/strong&gt;: &lt;a href="https://www.fidelisclayton.dev/20200304-elm-na-pratica-1"&gt;Imports, variáveis e o módulo HTML&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 2&lt;/strong&gt;: &lt;a href="https://www.fidelisclayton.dev/20200304-elm-na-pratica-2"&gt;The Elm Architecture, Records, funções e exibindo dados da Model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 3:&lt;/strong&gt; &lt;strong&gt;Events, Pattern Matching, Maybe, Dict e implementando a lógica do conversor&lt;/strong&gt; (Você está aqui)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 4&lt;/strong&gt;: &lt;em&gt;Type Signatures e adicionando tipos à nossa aplicação (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 5&lt;/strong&gt;: &lt;em&gt;Http, Commands, Browser.element e utilizando dados de uma API (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 6&lt;/strong&gt;: &lt;em&gt;Pipe e HttpBuilder (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 7&lt;/strong&gt;: &lt;em&gt;Configurando o ambiente de desenvolvimento local (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 8&lt;/strong&gt;: &lt;em&gt;Utilizando ports e flags (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 9&lt;/strong&gt;: &lt;em&gt;Trabalhando com rotas (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 10&lt;/strong&gt;: &lt;em&gt;Adicionando testes (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Continuando nosso conversor, hoje vamos implementar o cálculo da conversão e para isso vamos aprender algumas coisas novas: O pacote &lt;code&gt;Html.Events&lt;/code&gt;, &lt;code&gt;Pattern Matching&lt;/code&gt;, &lt;code&gt;Result&lt;/code&gt; e &lt;code&gt;Dict&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definindo as ações do usuário
&lt;/h2&gt;

&lt;p&gt;Antes de tudo vamos precisar definir quais são as ações que o usuário poderá executar dentro da aplicação, por enquanto ele poderá:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alterar a moeda de origem&lt;/li&gt;
&lt;li&gt;Alterar a moeda de destino&lt;/li&gt;
&lt;li&gt;Alterar a quantia que será convertido&lt;/li&gt;
&lt;li&gt;Clicar para calcular&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora vamos criar uma mensagem (a partir de agora vou chamar mensagem de &lt;code&gt;msg&lt;/code&gt;, é uma abreviação adotada por toda a comunidade de desenvolvedores Elm) para cada uma dessas ações, para isso vamos criar um &lt;strong&gt;Custom Type&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Type
&lt;/h3&gt;

&lt;p&gt;Ainda não entramos de cabeça no assunto tipos mas falando sem dar muitos detalhes, no Elm temos vários tipos predefinidos, por exemplo: &lt;code&gt;Boolean&lt;/code&gt;, &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;Float&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;List&lt;/code&gt;, e nós também podemos criar nossos próprios tipos sempre que for necessário, dando um exemplo simples, se quisermos criar nosso próprio tipo booleano poderiamos fazer dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Booleano&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Verdadeiro&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Falso&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Viu como é simples? Em um &lt;strong&gt;Custom Type&lt;/strong&gt; nós definimos quais são os possíveis valores que ele pode assumir, separados por uma barra vertical &lt;code&gt;|&lt;/code&gt;. Aqui vai mais um exemplo pra deixar mais claro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="c1"&gt;--   &amp;lt;nome do tipo&amp;gt;  = &amp;lt;valor 1&amp;gt; | &amp;lt;valor 2&amp;gt; | &amp;lt;valor 3&amp;gt; | &amp;lt;valor 4&amp;gt; | &amp;lt;valor 5&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Animal&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Dog&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Cat&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Cow&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Duck&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Fox&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora mais um detalhe sobre os &lt;strong&gt;Custom Types&lt;/strong&gt;, podemos associar dados à suas variações. Por exemplo, poderiamos descrever o progresso de uma requisição HTTP dessa maneira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;HttpProgress&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NotAsked&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;InProgress&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="kt"&gt;Data&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Presta atenção nos dois últimos valores, eles possuem um tipo após o nome do valor, isso quer dizer que a variação&lt;code&gt;Success&lt;/code&gt; possui um valor do tipo &lt;code&gt;Data&lt;/code&gt; e a variação &lt;code&gt;Error&lt;/code&gt; possui um valor do tipo &lt;code&gt;String&lt;/code&gt; que nesse caso pode ser uma mensagem de erro. Por exemplos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="kt"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john.doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Doe"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Something went wrong and we couldn't find the user"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Já entendeu onde quero chegar? Se você pensou que vamos criar um tipo para a nossa &lt;code&gt;msg&lt;/code&gt;, parabéns, você está certo. Então vamos lá:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;init =
&lt;/span&gt;    { from = "BRL"
    , to = "EUR"
    , amount = 0
    , result = 0
    }

+ type Msg
&lt;span class="gi"&gt;+       = ChangeOriginCurrency String
+       | ChangeDestinyCurrency String
+       | ChangeAmount String
+       | SubmitForm
&lt;/span&gt;
update msg model =
    model
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Aqui definimos que nossa &lt;code&gt;Msg&lt;/code&gt; pode assumir 4 possíveis valores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ChangeOriginCurrency&lt;/code&gt;: Alterar a moeda de origem&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ChangeDestinyCurrency&lt;/code&gt;: Alterar a moeda de destino&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ChangeAmount&lt;/code&gt;: Alterar a quantia que será convertida&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FormSubmitted&lt;/code&gt;: Clicar para calcular&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;ChangeOriginCurrency&lt;/code&gt;, &lt;code&gt;ChangeDestinyCurrency&lt;/code&gt; e &lt;code&gt;ChangeAmount&lt;/code&gt; vão receber o valor dos seus respectivos inputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coletando o input do usuário
&lt;/h2&gt;

&lt;p&gt;Antes de tudo vamos precisar coletar  as informações que o usuário inseriu no formulário, para isso iremos utilizar a biblioteca &lt;code&gt;Html.Events&lt;/code&gt;, é ela que possui funções como &lt;code&gt;onClick&lt;/code&gt;, &lt;code&gt;onInput&lt;/code&gt;, &lt;code&gt;onSubmit&lt;/code&gt; e várias outras. Vamos começar importando o &lt;code&gt;onInput&lt;/code&gt; e &lt;code&gt;onSubmit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;module Main exposing (main)
&lt;/span&gt;
import Browser
&lt;span class="p"&gt;import Html exposing (..)
import Html.Attributes exposing (class, type_, value, selected)
&lt;/span&gt;&lt;span class="gi"&gt;+ import Html.Events exposing (onInput, onSubmit)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Nós utilizamos os &lt;code&gt;Events&lt;/code&gt; da mesma forma que os &lt;code&gt;Attributes&lt;/code&gt;, passando eles na lista do primeiro argumento de uma tag HTML. Esses eventos precisam de um parâmetro que será a &lt;code&gt;msg&lt;/code&gt; a ser enviada para a função &lt;code&gt;update&lt;/code&gt;, vamos começar adicionar o evento de &lt;code&gt;onInput&lt;/code&gt; no campo de moeda de origem e passaremos a mensagem &lt;code&gt;ChangeOriginCurrency&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;[&lt;/span&gt; label [ class "block text-gray-700 text-sm font-bold mb-2" ] [ text "Moeda de origem" ]
  , div [ class "relative" ]
  [ select
&lt;span class="gd"&gt;-   [ class selectClasses, value model.from ]
&lt;/span&gt;&lt;span class="gi"&gt;+   [ class selectClasses, value model.from, onInput ChangeOriginCurrency ]
&lt;/span&gt;    [ option [ value "BRL", selected (model.from == "BRL") ] [ text "Real" ] 
      , option [ value "USD", selected (model.from == "USD") ] [ text "Dólar americano" ]
      , option [ value "EUR", selected (model.from == "EUR") ] [ text "Euro" ] 
    ]
  ]
&lt;span class="err"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Talvez você tenha percebido que não passamos nenhum parâmetro para a &lt;code&gt;msg&lt;/code&gt; &lt;code&gt;ChangeOriginCurrency&lt;/code&gt;, isso se deve ao fato de que o &lt;code&gt;onInput&lt;/code&gt; vai fazer isso para nós automaticamente. Agora vamos checar se isso está funcionando, vamos mudar o valor da moeda de origem e utilizar o debugger para ver se a mensagem foi emitida:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mTI1jhF2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.fidelisclayton.dev/01104f89c919576c70de05f032bf4565/image-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mTI1jhF2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.fidelisclayton.dev/01104f89c919576c70de05f032bf4565/image-1.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O valor do input da moeda de origem não mudou quando selecionamos outra moeda, isso aconteceu por quê ainda não implementamos isso na função &lt;code&gt;update&lt;/code&gt; mas quando abrimos o &lt;strong&gt;Debugger&lt;/strong&gt; (no menu superior direto) vimos que a mensagem foi enviada, e observe que a barra lateral esquerda mostra as duas mensagens que foram emitidas por que mudamos a moeda duas vezes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PSRLYpp5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/b6ce2123e3c28901ebf6dbf45cd8f6ba/99072/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PSRLYpp5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/b6ce2123e3c28901ebf6dbf45cd8f6ba/99072/image-2.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos adicionar as outras mensagens no nosso HTML para finalmente implementar o &lt;code&gt;update&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adicionando a mensagem de submit no formulário:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-, form [ class "bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" ]
&lt;/span&gt;&lt;span class="gi"&gt;+, form [ onSubmit SubmitForm, class "bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" ]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adicionando a mensagem no input da moeda de destino&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;[&lt;/span&gt; label [ class "block text-gray-700 text-sm font-bold mb-2" ]
    [ text "Moeda de destino"
    ]
&lt;span class="err"&gt;,&lt;/span&gt; div [ class "relative" ]
    [ select
&lt;span class="gd"&gt;-       [ class selectClasses, value model.to ]
&lt;/span&gt;&lt;span class="gi"&gt;+       [ class selectClasses, value model.to, onInput ChangeDestinyCurrency ]
&lt;/span&gt;        [ option [ value "USD", selected (model.to == "USD") ] [ text "Dólar americano" ]
        , option [ value "BRL", selected (model.to == "BRL") ] [ text "Real" ]
        , option [ value "EUR", selected (model.to == "EUR") ] [ text "Euro" ]
        ]
    ]
&lt;span class="err"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adicionando a mensagem no input da quantia a ser convertida:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;[&lt;/span&gt; label [ class "block text-gray-700 text-sm font-bold mb-2" ]
    [ text "Quantidade"
    ]
&lt;span class="gd"&gt;-, input [ type_ "number", value (String.fromFloat model.amount), class "shadow appearence-none border rounded w-full py-2 px-3 text-gray" ] []
&lt;/span&gt;&lt;span class="gi"&gt;+, input [ type_ "number", onInput ChangeAmount, value (String.fromFloat model.amount), class "shadow appearence-none border rounded w-full py-2 px-3 text-gray" ] []
&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Código até agora: &lt;a href="https://ellie-app.com/88LQtVdRPxka1"&gt;https://ellie-app.com/88LQtVdRPxka1&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementando a função update
&lt;/h2&gt;

&lt;p&gt;Agora que todos os eventos estão no lugar, chegou o tão esperado momento de implementar o &lt;code&gt;update&lt;/code&gt;, então vamos lâ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;update msg model =
&lt;/span&gt;&lt;span class="gd"&gt;-   model
&lt;/span&gt;&lt;span class="gi"&gt;+   case msg of
+       ChangeOriginCurrency currencyCode -&amp;gt;
+           { model | from = currencyCode }
+
+       ChangeDestinyCurrency currencyCode -&amp;gt;
+           { model | to = currencyCode }
+
+       ChangeAmount amount -&amp;gt;
+           { model | amount = amount }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Aha! Achou que não iriamos aprender nada novo? Te apresento o &lt;strong&gt;Pattern Matching&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pattern Matching
&lt;/h3&gt;

&lt;p&gt;O Pattern Matching está bem presente nas linguagens funcionais, no Elm ele aparece na forma &lt;code&gt;case ... of&lt;/code&gt; e nos possibilita tratar diferentes "branchs" (possibilidades)  de um determinado valor. Aqui vai um exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Cat&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Cow&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Duck&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Fox&lt;/span&gt;

&lt;span class="n"&gt;makeSound&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;woof"&lt;/span&gt;
        &lt;span class="kt"&gt;Cat&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meow"&lt;/span&gt;
        &lt;span class="kt"&gt;Cow&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moo"&lt;/span&gt;
        &lt;span class="kt"&gt;Duck&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quack"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A sintaxe não é muito complexa, iniciamos com &lt;code&gt;case &amp;lt;nome da variável&amp;gt; of&lt;/code&gt; e em seguida listamos cada possível valor e após a seta (&lt;code&gt;-&amp;gt;&lt;/code&gt;) podemos retornar algo baseado no valor.&lt;/p&gt;

&lt;p&gt;Um fato muito importante sobre o &lt;code&gt;case ... of&lt;/code&gt; é que você obrigatóriamente precisa tratar todos os possíveis casos, se tentarmos compilar o código acima, o compilador vai nos avisar que esquecemos de tratar um dos possiveis valores (&lt;code&gt;Fox&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ae6W-ekn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/c446c2694389b216225723f743c43173/99072/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ae6W-ekn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/c446c2694389b216225723f743c43173/99072/image-3.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso é uma das coisas que contribuem para que uma aplicação Elm nunca cause erros enquanto está sendo executada, o compilador faz com que seja impossível deixar pontas soltas. Para corrigir isso basta adicionar a "branch" que não foi tratada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;type Animal = Dog | Cat | Cow | Duck | Fox
&lt;/span&gt;
makeSound animal =
    case animal of
        Dog -&amp;gt; "woof"
        Cat -&amp;gt; "meow"
        Cow -&amp;gt; "moo"
        Duck -&amp;gt; "quack"
&lt;span class="gi"&gt;+       Fox -&amp;gt; "Ring-ding-ding-ding-dingeringeding!"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;O uso do &lt;code&gt;case ... of&lt;/code&gt; não se limita a Custom Types, pode ser utilizado com vários outros tipos, como &lt;strong&gt;String&lt;/strong&gt;, &lt;strong&gt;List&lt;/strong&gt;, &lt;strong&gt;Dict&lt;/strong&gt; e vários outros.&lt;/p&gt;

&lt;p&gt;Com o &lt;code&gt;case .. of&lt;/code&gt; também conseguimos acessar os valores associados a uma determinada branch, como fizemos com o nosso &lt;code&gt;update&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
    &lt;span class="c1"&gt;-- Nome da mensagem    Valor associado&lt;/span&gt;
    &lt;span class="c1"&gt;--       |                   |&lt;/span&gt;
    &lt;span class="c1"&gt;--       v                   V&lt;/span&gt;
        &lt;span class="kt"&gt;ChangeOriginCurrency&lt;/span&gt; &lt;span class="n"&gt;currencyCode&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;--                           ^&lt;/span&gt;
    &lt;span class="c1"&gt;--                           |&lt;/span&gt;
    &lt;span class="c1"&gt;--            Aqui embaixo utilizamos esse valor&lt;/span&gt;
    &lt;span class="c1"&gt;--                           |&lt;/span&gt;
    &lt;span class="c1"&gt;--                           V&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;currencyCode&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora voltando ao nosso código (que no momento está assim: &lt;a href="https://ellie-app.com/88MrJPM5Bmza1"&gt;https://ellie-app.com/88MrJPM5Bmza1&lt;/a&gt;), se tentarmos compilar receberemos o seguinte erro:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JJhi2p7b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/74202dd2e92c41f7d2b658566a107fbe/99072/image-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JJhi2p7b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/74202dd2e92c41f7d2b658566a107fbe/99072/image-4.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O compilador está dizendo que estamos definindo o &lt;code&gt;amount&lt;/code&gt; com um valor do tipo &lt;code&gt;String&lt;/code&gt; &lt;em&gt;[1]&lt;/em&gt; mas que na verdade o &lt;code&gt;amount&lt;/code&gt; é do tipo &lt;code&gt;Float&lt;/code&gt; &lt;em&gt;[2]&lt;/em&gt;. No final &lt;em&gt;[3]&lt;/em&gt; do erro ele nos dá uma dica: "&lt;strong&gt;&lt;em&gt;Quer converter uma String para Float? Use a função &lt;code&gt;String.toFloat&lt;/code&gt;!&lt;/em&gt;&lt;/strong&gt;". Perfeito! Era justamente isso que a gente precisava. De fato não estavamos convertendo os valores, observe o trecho seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="kt"&gt;ChangeAmount&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;ChangeAmount&lt;/code&gt; nos trás o valor como &lt;code&gt;String&lt;/code&gt; por que é o que recebemos do &lt;code&gt;input&lt;/code&gt;, logo precisaremos converter o amount para &lt;code&gt;Float&lt;/code&gt; utilizando a função &lt;code&gt;String.toFloat&lt;/code&gt;. Então vamos nessa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;update msg model =
&lt;/span&gt;    case msg of
        ChangeOriginCurrency currencyCode -&amp;gt;
            { model | from = currencyCode }

        ChangeDestinyCurrency currencyCode -&amp;gt;
            { model | to = currencyCode }

        ChangeAmount amount -&amp;gt;
&lt;span class="gd"&gt;-            { model | amount = amount }
&lt;/span&gt;&lt;span class="gi"&gt;+            { model | amount = String.toFloat amount }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora deve dar tudo certo né? Errado! Repara na mensagem de erro:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j8sz9XLo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/ac3d09aef4356937dc3fddbc00d2fbe1/cda19/image-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j8sz9XLo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/ac3d09aef4356937dc3fddbc00d2fbe1/cda19/image-5.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Novamente os tipos não combinam, dessa vez estamos passando o tipo &lt;code&gt;Maybe Float&lt;/code&gt; &lt;em&gt;[1]&lt;/em&gt; mas o esperado é &lt;code&gt;Float&lt;/code&gt; &lt;em&gt;[2]&lt;/em&gt;. Mais uma coisa nova pra você, o tipo &lt;strong&gt;Maybe&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entendendo o Maybe
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;Maybe&lt;/strong&gt; é um tipo que representa um valor que talvez não exista. Ficou meio confuso né? Deixa eu dar alguns exemplos de "valores que talvez não existam":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pegar o primeiro item de uma lista de números&lt;/strong&gt;: O resultado dessa operação deve ser representado por um &lt;strong&gt;Maybe&lt;/strong&gt; pois existe a possibilidade da lista não possuir o primeiro item, por exemplo quando ela estiver vazia.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pegar o último item de uma lista de números&lt;/strong&gt;: Mesma coisa do exemplo anterior, se a lista estiver vazia não existirá o último item, logo, o resultado deve ser representado por um &lt;strong&gt;Maybe&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Converter uma String para Float&lt;/strong&gt;: Aqui é o caso que estamos enfrentando, existe a possibilidade de uma String não ser convertida para Float. Alguns exemplos:

&lt;ul&gt;
&lt;li&gt;"&lt;code&gt;10"&lt;/code&gt;: pode ser convertido pois representa um número&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"Dez"&lt;/code&gt;, "Elm": não pode ser convertido pois não é um número.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Percebeu o quanto esse tipo é importante? O &lt;strong&gt;Maybe&lt;/strong&gt; possui duas branchs: &lt;code&gt;Just value&lt;/code&gt; e &lt;code&gt;Nothing&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Nothing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Isso significa que um &lt;strong&gt;Maybe&lt;/strong&gt; pode ter um valor (&lt;code&gt;Just&lt;/code&gt;) ou nada (&lt;code&gt;Nothing&lt;/code&gt;). Alguns exemplos para fixar melhor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primeiro item da lista &lt;code&gt;[]&lt;/code&gt; (vazia): &lt;code&gt;Nothing&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Primeiro item da lista &lt;code&gt;[1, 2, 3, 4]&lt;/code&gt;: &lt;code&gt;Just 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Convertendo &lt;code&gt;"Elm"&lt;/code&gt; para float: &lt;code&gt;Nothing&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Convertendo &lt;code&gt;"10"&lt;/code&gt; para float: &lt;code&gt;Just 10&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Podemos pegar o valor de um &lt;strong&gt;Maybe&lt;/strong&gt; utilizando o &lt;code&gt;case .. of&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toFloat&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O valor é "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O resultado da conversão é inválido."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora voltando ao nosso conversor, vamos tratar o &lt;code&gt;Maybe Float&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;update msg model =
&lt;/span&gt;    case msg of
        ChangeOriginCurrency currencyCode -&amp;gt;
            { model | from = currencyCode }

        ChangeDestinyCurrency currencyCode -&amp;gt;
            { model | to = currencyCode }

        ChangeAmount amount -&amp;gt;
&lt;span class="gd"&gt;-            { model | amount = String.toFloat amount }
&lt;/span&gt;&lt;span class="gi"&gt;+            case String.toFloat amount of
+               Just value -&amp;gt;
+                   { model | amount = value }
+               Nothing -&amp;gt;
+                   model
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Neste caso, se receber-mos &lt;code&gt;Nothing&lt;/code&gt; não faremos nada e retornaremos a model sem modificações.&lt;/p&gt;

&lt;p&gt;Agora clique para compilar, provavelmente não vai funciona pois não implementamos o &lt;code&gt;SubmitForm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Pbl6od_l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/121a02a83e64d69f41f5fd7d542b3667/c83ae/image-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Pbl6od_l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/121a02a83e64d69f41f5fd7d542b3667/c83ae/image-6.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O código atualizado está aqui: &lt;a href="https://ellie-app.com/88MZ6t4bmnba1"&gt;https://ellie-app.com/88MZ6t4bmnba1&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calculando a conversão
&lt;/h2&gt;

&lt;p&gt;Chegamos na última e principal função da nossa aplicação, agora vamos implementar a conversão das moedas. &lt;/p&gt;

&lt;p&gt;Antes de tudo, precisamos dos valores das moedas, até agora não temos eles. Pra facilitar as coisas vamos inventar uma variável com alguns valores fictícios. Para isso vou utilizar uma estrutura de dados do tipo &lt;code&gt;Dict&lt;/code&gt; para nos auxiliar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entendendo o Dict
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;Dict&lt;/strong&gt; é bem parecido com o &lt;strong&gt;Record&lt;/strong&gt; que aprendemos no tutorial anterior. Ele possui chaves e valores mas suas chaves podem ser do tipo &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;Float&lt;/code&gt;, &lt;code&gt;Time&lt;/code&gt;, &lt;code&gt;Char&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt; e alguns outros.&lt;/p&gt;

&lt;p&gt;Podemos criar um Dict dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;myDict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromList&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chave1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chave2"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;E temos funções para inserir, atualizar, e recuperar valores dele:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chave3"&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;myDict&lt;/span&gt;
&lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chave3"&lt;/span&gt; &lt;span class="n"&gt;myDict&lt;/span&gt;
&lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chave3"&lt;/span&gt; &lt;span class="n"&gt;myDict&lt;/span&gt; &lt;span class="c1"&gt;-- vai retornar um Maybe pois é possível que a chave não exista no Dict&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora vamos criar algumas variáveis para as nossas moedas utilizando o &lt;strong&gt;Dict&lt;/strong&gt;, primeiro vamos importar o módulo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;module Main exposing (main)
&lt;/span&gt;
import Browser
&lt;span class="gi"&gt;+ import Dict
&lt;/span&gt;&lt;span class="p"&gt;import Html exposing (..)
import Html.Attributes exposing (class, selected, type_, value)
import Html.Events exposing (onInput, onSubmit)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Em seguida vamos criar as variáveis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;selectClasses =
&lt;/span&gt;    "block appearance-none w-full border shadow py-2 px-3 pr-8 rounded"

+ brl =
&lt;span class="gi"&gt;+     Dict.fromList
+         [ ( "EUR", 0.21 )
+         , ( "USD", 0.23 )
+         ]
+
+ usd =
+     Dict.fromList
+         [ ( "EUR", 0.92 )
+         , ( "BRL", 4.42 )
+         ]
+
+ eur =
+     Dict.fromList
+         [ ( "USD", 1.09 )
+         , ( "BRL", 4.81 )
+         ]
+
+ currencies =
+     Dict.fromList
+         [ ( "BRL", brl )
+         , ( "EUR", eur )
+         , ( "USD", usd )
+         ]
&lt;/span&gt;
init =
    { from = "BRL"
    , to = "EUR"
    , amount = 0
    , result = 0
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;E agora no &lt;code&gt;update&lt;/code&gt; implementaremos a conversão da seguinte maneira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;update msg model =
&lt;/span&gt;    case msg of
        ChangeOriginCurrency currencyCode -&amp;gt;
            { model | from = currencyCode }

        ChangeDestinyCurrency currencyCode -&amp;gt;
            { model | to = currencyCode }

        ChangeAmount amount -&amp;gt;
            case String.toFloat amount of
                Just value -&amp;gt;
                    { model | amount = value }

                Nothing -&amp;gt;
                    model
&lt;span class="gi"&gt;+
+       SubmitForm -&amp;gt;
+           case Dict.get model.from currencies of
+               Just availableCurrencies -&amp;gt;
+                   case Dict.get model.to availableCurrencies of
+                       Just toCurrency -&amp;gt;
+                           { model | result = toCurrency * model.amount }
+
+                       Nothing -&amp;gt;
+                           model
+
+               Nothing -&amp;gt;
+                   model
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pronto!&lt;/strong&gt; Copia esse código, clica para compilar, adiciona um valor para converter e clica para converter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6UBENrFo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.fidelisclayton.dev/632c4affbfde6d0b392511701b666b6b/image-7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6UBENrFo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.fidelisclayton.dev/632c4affbfde6d0b392511701b666b6b/image-7.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas nem tudo são flores, o código está um pouco confuso né?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;        &lt;span class="kt"&gt;SubmitForm&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="c1"&gt;-- Aqui vamos pegar os valores de conversão da moeda de origem&lt;/span&gt;
            &lt;span class="c1"&gt;-- Por exemplo, se `model.from` for "BRL":&lt;/span&gt;
            &lt;span class="c1"&gt;-- Dict.get "BRL" currencies&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;currencies&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                    &lt;span class="c1"&gt;-- Caso essa moeda exista no `currencies` teremos acesso a ela&lt;/span&gt;
                    &lt;span class="c1"&gt;-- no `Just`&lt;/span&gt;
                &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;availableCurrencies&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="c1"&gt;-- Utilizando o resultado `availableCurrencies` vamos tentar pegar o valor&lt;/span&gt;
                    &lt;span class="c1"&gt;-- da moeda destino.&lt;/span&gt;
                    &lt;span class="c1"&gt;-- Por exemplo, se `model.to` for "EUR":&lt;/span&gt;
                    &lt;span class="c1"&gt;-- Dict.get "EUR" availableCurrencies&lt;/span&gt;
                    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;availableCurrencies&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                         &lt;span class="c1"&gt;-- Se conseguir-mos pegar o valor, calcular o resultado&lt;/span&gt;
                         &lt;span class="c1"&gt;-- multiplicando o valor da moeda (destinyCurrencyValue) pela&lt;/span&gt;
                         &lt;span class="c1"&gt;-- quantia a ser convertida (model.amount)&lt;/span&gt;
                        &lt;span class="kt"&gt;Just&lt;/span&gt; &lt;span class="n"&gt;destinyCurrencyValue&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;destinyCurrencyValue&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="c1"&gt;-- Caso a moeda não seja encontrada, iremos definir o `result` como 0&lt;/span&gt;
                        &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="c1"&gt;-- Caso a moeda não seja encontrada, iremos definir o `result` como 0&lt;/span&gt;
                &lt;span class="kt"&gt;Nothing&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Temos três &lt;code&gt;case .. of&lt;/code&gt; aninhados e isso dificulta um pouco a legibilidade e a manutenção do código, então vamos melhorar isso um pouco. Fique a vontade para pegar o código atualizado: &lt;a href="https://ellie-app.com/88NKHgZrtQWa1"&gt;https://ellie-app.com/88NKHgZrtQWa1&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utilizando o &lt;code&gt;let ... in&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;let ... in&lt;/code&gt; permite que a gente defina valores dentro de uma expressão, assim poderemos guardar valores para utilizar depois. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;soma&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
        &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O resultado é: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora vamos refatorar a nossa função:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;SubmitForm -&amp;gt;
&lt;/span&gt;&lt;span class="gd"&gt;-   case Dict.get model.from currencies of
-       Just availableCurrencies -&amp;gt;
-           case Dict.get model.to availableCurrencies of
-               Just destinyCurrencyValue -&amp;gt;
-                   { model | result = destinyCurrencyValue * model.amount }
-               Nothing -&amp;gt;
-                   model
-       Nothing -&amp;gt;
-           model
&lt;/span&gt;&lt;span class="gi"&gt;+ let
+     availableCurrencies =
+         Maybe.withDefault Dict.empty (Dict.get model.from currencies)
+
+     destinyCurrencyValue =
+         Maybe.withDefault 0 (Dict.get model.to availableCurrencies)
+
+     result =
+         destinyCurrencyValue * model.amount
+ in
+     { model | result = result }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;BEM&lt;/strong&gt; melhor não é mesmo? Para isso, além do &lt;code&gt;let ... in&lt;/code&gt; utilizei a função &lt;code&gt;Maybe.withDefault&lt;/code&gt; para facilitar as coisas por aqui. O &lt;code&gt;Maybe.withDefault&lt;/code&gt; nos permite definir um valor padrão caso o segundo parâmetro seja &lt;code&gt;Nothing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aqui dizemos que o valor padrão para o resultado de &lt;code&gt;Dict.get model.from currencies&lt;/code&gt; é um Dict vazio (&lt;code&gt;Dict.empty&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;availableCurrencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Maybe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;withDefault&lt;/span&gt; &lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;currencies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Em seguida definimos que o valor padrão para o resultado de &lt;code&gt;Dict.get model.to availabileCurrencies&lt;/code&gt; é &lt;code&gt;0&lt;/code&gt; (zero):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;destinyCurrencyValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Maybe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;withDefault&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Dict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;availableCurrencies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;E por fim calculamos o resultado e atualizamos a model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;destinyCurrencyValue&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;
&lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ainda dá para melhorar esse código mais um pouquinho mas vou deixar isso para os próximos tutoriais.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Finalmente implementamos todas as funcionalidades do conversor, agora ele de fato converte as moedas 🎉. Mas ainda temos vários pontos para melhorar e que poderemos explorar novas APIs e conceitos do Elm.&lt;/p&gt;

&lt;p&gt;Esse tutorial foi bastante denso e cheio de coisas novas, então não fique chateado caso não tenha entendido tudo, alguns desses conceitos podem demorar dias para serem de fato aprendidos. Sugiro que você tente fazer uma outra aplicação utilizando tudo o que aprendeu até agora, dessa forma você irá escalar a curva de aprendizado do Elm bem mais rápido.&lt;/p&gt;

&lt;p&gt;No próximo tutorial iremos aprender a ler assinatura de tipos e tipar nossa aplicação, assim o compilador irá nos ajudar mais. Eu particularmente estou bastante animado com o que está por vir.&lt;/p&gt;

&lt;p&gt;Como sempre, o código atualizado está disponível neste link: &lt;a href="https://ellie-app.com/88NYGqX6QzVa1"&gt;https://ellie-app.com/88NYGqX6QzVa1&lt;/a&gt;. Quando a parte 4 estiver pronta irei deixar o link aqui. Até a próxima!&lt;/p&gt;

</description>
      <category>elm</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>functional</category>
    </item>
    <item>
      <title>Elm na prática - The Elm Architecture, Records, funções e exibindo dados da Model</title>
      <dc:creator>Clayton Fidelis</dc:creator>
      <pubDate>Tue, 03 Mar 2020 16:30:09 +0000</pubDate>
      <link>https://dev.to/fidelisclayton/elm-na-pratica-the-elm-architecture-records-funcoes-e-exibindo-dados-da-model-49fp</link>
      <guid>https://dev.to/fidelisclayton/elm-na-pratica-the-elm-architecture-records-funcoes-e-exibindo-dados-da-model-49fp</guid>
      <description>&lt;p&gt;Neste tutorial vamos dar vida ao nosso conversor de moedas, se você não viu a parte 1 dessa série de tutoriais, corre lá e dá uma olhada, o link para o código de onde paramos está disponível neste link: &lt;a href="https://ellie-app.com/88hp8WgJd5Ca1"&gt;https://ellie-app.com/88hp8WgJd5Ca1&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parte 1&lt;/strong&gt;: &lt;a href="https://www.fidelisclayton.dev/20200304-elm-na-pratica-1"&gt;Imports, variáveis e o módulo HTML&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 2&lt;/strong&gt;: &lt;strong&gt;The Elm Architecture, Records, funções e exibindo dados da Model&lt;/strong&gt; (Você está aqui)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 3:&lt;/strong&gt; &lt;a href="https://www.fidelisclayton.dev/20200304-elm-na-pratica-3"&gt;Events, Pattern Matching, Maybe, Dict e implementando a lógica do conversor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 4&lt;/strong&gt;: &lt;em&gt;Type Signatures e adicionando tipos à nossa aplicação (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 5&lt;/strong&gt;: &lt;em&gt;Http, Commands, Browser.element e utilizando dados de uma API (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 6&lt;/strong&gt;: &lt;em&gt;Pipe e HttpBuilder (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 7&lt;/strong&gt;: &lt;em&gt;Configurando o ambiente de desenvolvimento local (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 8&lt;/strong&gt;: &lt;em&gt;Utilizando ports e flags (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 9&lt;/strong&gt;: &lt;em&gt;Trabalhando com rotas (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 10&lt;/strong&gt;: &lt;em&gt;Adicionando testes (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Elm Architecture
&lt;/h2&gt;

&lt;p&gt;Antes de colocar-mos a mão no código, vamos entender como a arquitetura do Elm funciona. Até agora só renderizamos uma tela utilizando as funções do pacote HTML, mas só com isso não vamos conseguir construir algo realmente útil, onde um usuário pode interagir com a nossa aplicação. Para isso, vamos utilizar algumas funções do pacote &lt;code&gt;Browser&lt;/code&gt; que implementam a &lt;strong&gt;Arquitetura do Elm&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A forma mais básica dessa arquitetura é dividida em 3 partes:&lt;/p&gt;

&lt;h3&gt;
  
  
  Model
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Model&lt;/strong&gt; representa o estado inicial da nossa aplicação, é nela que informamos como será a estrutura de dados da nossa aplicação. Usando nosso conversor como exemplo, a &lt;strong&gt;model&lt;/strong&gt; dele será assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BRL"&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD"&lt;/span&gt;
    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  view
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;view&lt;/strong&gt; é uma função que recebe a &lt;strong&gt;model&lt;/strong&gt; da aplicação como parâmetro e retorna um Html. Essa parte já vimos no tutorial anterior, a única diferença aqui é que com a função &lt;code&gt;view&lt;/code&gt; podemos trabalhar com os dados do estado da aplicação. Continuando o exemplo anterior, poderiamos utilizar a &lt;code&gt;model&lt;/code&gt; para exibir seus dados para o usuário desta forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Convertendo "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; para "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  update
&lt;/h3&gt;

&lt;p&gt;A função &lt;strong&gt;update&lt;/strong&gt; é o cérebro da arquitetura, é responsável por fazer as atualizações na &lt;strong&gt;model&lt;/strong&gt; e precisa de dois parâmetros para funcionar, o primeiro é uma "mensagem" e o segundo é a &lt;strong&gt;model&lt;/strong&gt; atual. Seguindo com o exemplo do nosso contador, uma forma muito simples de escrever a funçāo &lt;strong&gt;update&lt;/strong&gt; seria essa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mudar moeda de origem para BRL"&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BRL"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mudar moeda de origem para USD"&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Utilizamos a mensagem para decidir como vamos atualizar a model, mas não de apegue a esse exemplo, essa é uma forma bem básica para mostrar como implementar uma função update e em breve aprenderemos uma forma melhor de implementar essa função.&lt;/p&gt;

&lt;h3&gt;
  
  
  Juntando tudo
&lt;/h3&gt;

&lt;p&gt;Para que as 3 partes possam conversar, precisaremos utilizar a função &lt;code&gt;Browser.sandbox&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sandbox&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;sandbox&lt;/code&gt; é a forma mais simples de utilizar a arquitetura Elm, logo, possui algumas limitações, como por exemplo, uma aplicação &lt;code&gt;sandbox&lt;/code&gt; não consegue se comunicar com o "mundo exterior", ou seja, você não vai conseguir fazer requisições para servidores ou chamar funções do JavaScript (sim, isso é possível). Por ora, ela será perfeita para nosso caso de uso.&lt;/p&gt;

&lt;p&gt;Toda vez que o usuário utiliza alguma função na nossa aplicação, a &lt;code&gt;view&lt;/code&gt; vai emitir uma mensagem desencadeando uma série de atualizações:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3qh3zylu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/a62afc50d0ac7f716bb3ba77c9c466eb/99072/image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3qh3zylu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/a62afc50d0ac7f716bb3ba77c9c466eb/99072/image-1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementando a arquitetura Elm
&lt;/h2&gt;

&lt;p&gt;Agora que já entendemos como funciona a arquitetura do Elm, vamos implementar ela no nosso conversor.&lt;/p&gt;

&lt;p&gt;Primeiro vamos importar o módulo &lt;code&gt;Browser&lt;/code&gt;, ele possui a função &lt;code&gt;sandbox&lt;/code&gt; que vai ser responsável por juntar a &lt;code&gt;view&lt;/code&gt;, &lt;code&gt;model&lt;/code&gt; e &lt;code&gt;update&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;module Main exposing (main)
&lt;/span&gt;
+ import Browser
&lt;span class="p"&gt;import Html exposing (..)
import Html.Attributes exposing (class, type_, value)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Em seguida vamos criar a função &lt;code&gt;update&lt;/code&gt; e o &lt;code&gt;init&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;selectClasses =
&lt;/span&gt;    "block appearance-none w-full border shadow py-2 px-3 pr-8 rounded"

+ init =
&lt;span class="gi"&gt;+    { from = "BRL"
+    , to = "EUR"
+    , amount = 0
+    , result = 0
+    }
&lt;/span&gt;
+ update msg model =
&lt;span class="gi"&gt;+    model
&lt;/span&gt;
main =
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora vamos renomear a função &lt;code&gt;main&lt;/code&gt; para &lt;code&gt;view&lt;/code&gt; e fazer com que ela receba a model como parãmetro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- main =
&lt;/span&gt;&lt;span class="gi"&gt;+ view model =
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;E para finalizar, no final do arquivo vamos criar a nova &lt;code&gt;main&lt;/code&gt; utilizando o &lt;code&gt;Browser.sandbox&lt;/code&gt; para colocar tudo em ordem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sandbox&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Bom, com esse novo código introduzimos uma série de novos conceitos, então vamos por partes:&lt;/p&gt;

&lt;h2&gt;
  
  
  Record
&lt;/h2&gt;

&lt;p&gt;Quando criamos o &lt;code&gt;init&lt;/code&gt;, utilizamos uma estrutura de dados chamada &lt;strong&gt;Record&lt;/strong&gt;, ela possui chaves e valores para representar alguma informação, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;kobe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Kobe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bryant"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lakers"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;championships&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A sintaxe é simples, iniciamos um record utilizando uma chave (&lt;code&gt;{&lt;/code&gt;) e em seguida informamos quais são as "chaves" e "valores" que esse record possui, e cada par de chave e valor é separado por vírgula e no final fechamos a chave (&lt;code&gt;}&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;myRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;chave1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valor 1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chave2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valor 2"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chave3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valor 3"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Acessando valores de um Record
&lt;/h3&gt;

&lt;p&gt;Temos duas formas de acessar os valores de um Record no Elm, a primeira é a forma mais tradicional e que está presente em todas as linguagens de programação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;kobe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;
&lt;span class="n"&gt;kobe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;
&lt;span class="n"&gt;kobe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A segunda forma de acessar um valor de um Record é através de funções que o Elm disponibiliza com o nome da propriedade do record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt; &lt;span class="n"&gt;kobe&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt; &lt;span class="n"&gt;kobe&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;kobe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Um ponto que vale muito a pena mencionar é que em nenhuma das duas formas permite que você tente acessar uma chave que não existe no record, caso tente, o compilador vai te alertar. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;kobe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;middleName&lt;/span&gt; &lt;span class="c1"&gt;-- middleName não existe no record, logo não irá compilar&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="n"&gt;kobe&lt;/span&gt; &lt;span class="c1"&gt;-- height não existe no record, logo não irá compilar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Atualizando valores de um Record
&lt;/h3&gt;

&lt;p&gt;A forma de atualizar um valor de um Record é diferente da maioria das outras linguagens de programação, a forma padrão de fazer isso na maioria delas é definindo o valor diretamente, algo parecido com isso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;kobe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;No Elm, isso não é permitido, como utilizamos estrutura de dados imutáveis (falaremos sobre isso no futuro), não podemos modificar um valor. Para fazer isso no Elm, precisamos criar uma nova cópia do valor anterior mas atualizando os campos que precisamos, no Elm fazemos isso dessa maneira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;kobe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lê-se: "Pega tudo do record &lt;code&gt;kobe&lt;/code&gt; e atualiza a propriedade &lt;code&gt;number&lt;/code&gt; com o valor &lt;code&gt;24&lt;/code&gt;".&lt;/p&gt;

&lt;p&gt;Também podemos atualizar várias propriedades ao mesmo tempo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;kobe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USA National Team"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Também vale salientar que não podemos adicionar uma propriedade que não existe no record original, caso a gente tente, o código não irá compilar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;kobe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;198&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;-- Não irá compilar pois a propriedade height não existe no record original&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Funções
&lt;/h2&gt;

&lt;p&gt;Outro conceito que introduzimos aqui foram as funções, talvez você nem tenha percebido pois a sintaxe delas é bem limpa, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;soma&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="n"&gt;subtrai&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="n"&gt;multiplica&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="n"&gt;divide&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Viu como é simples? Não utilizamos parênteses, vírgulas ou chaves para definir uma função. Primeiro definimos o nome da função, em seguida seus argumentos separados por espaço, após os argumentos utilizamos o sinal de igualdade (&lt;code&gt;=&lt;/code&gt;) para separar a definição da função e o corpo. Tudo após o sinal de igualdade faz parte do corpo da função.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="n"&gt;da&lt;/span&gt; &lt;span class="n"&gt;funcao&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;primeiro&lt;/span&gt; &lt;span class="n"&gt;argumento&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;segundo&lt;/span&gt; &lt;span class="n"&gt;argumento&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;corpo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;soma&lt;/span&gt;              &lt;span class="n"&gt;a&lt;/span&gt;                    &lt;span class="n"&gt;b&lt;/span&gt;                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ah, reparou que também não utilizamos nenhuma &lt;code&gt;return&lt;/code&gt;? No Elm, o valor no fim de uma expressão sempre será retornado.&lt;/p&gt;

&lt;p&gt;Talvez você esteja se perguntando como sabemos que o corpo de uma função terminou se a gente não utilizou nenhum caractère para delimitar o corpo, a resposta é simples, o corpo é delimitado pela identação do código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;soma&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="c1"&gt;-- fim da função "soma"&lt;/span&gt;

&lt;span class="n"&gt;subtrai&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="c1"&gt;-- fim da função "subtrai"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora voltando ao nosso exemplo. Lembra que criamos a função &lt;code&gt;update&lt;/code&gt;? Dá uma olhadinha nela agora, aposto que você vai entender melhor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Repara que nós criamos ela e imediatamente retornamos o valor da model, vamos deixar ela assim por enquanto só para conseguirmos compilar a aplicação, já já iremos implementar a lógica dela.&lt;/p&gt;

&lt;p&gt;Acredito que com essa explicação conseguiremos prosseguir sem muitos problemas, mas antes, clique para compilar o código e vamos nos certificar de que irá compilar sem erros. Tudo certo? Então vamos continuar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Renderizando a model na view
&lt;/h2&gt;

&lt;p&gt;Agora vamos utilizar a &lt;code&gt;view&lt;/code&gt; para exibir os dados da &lt;code&gt;model&lt;/code&gt;, então vamos exibir o valor &lt;code&gt;result&lt;/code&gt; da model (que no futuro iremos utilizar para salvar o resultado da conversão) logo após o botão:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;                , div [ class "mb-6" ]
                    [ label [ class "block text-gray-700 text-sm font-bold mb-2" ]
                        [ text "Quantidade"
                        ]
                    , input [ type_ "number", class "shadow appearence-none border rounded w-full py-2 px-3 text-gray" ] []
                    ]
                , div [ class "flex w-full" ]
                    [ button [ class "bg-blue-500 w-full hover:bg-blue-700 text-white font-bold py-2 px-4" ] [ text "Converter" ] ]
&lt;span class="gi"&gt;+               , div [ class "flex w-full text-center mt-5 text-gray-700 text-sm" ]
+                   [ text ("Convertendo " ++ String.fromFloat model.amount ++ " " ++ model.from ++ " para " ++ model.to ++ " totalizando " ++ String.fromFloat model.result ++ " " ++ model.to) ]
&lt;/span&gt;               ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Após compilar nossa tela ficará assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G4AJe_iy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/3f75946804c40cba9ae38570493a09e9/c83ae/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G4AJe_iy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/3f75946804c40cba9ae38570493a09e9/c83ae/image-2.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repara que agora estamos exibindo os dados da model no final do formulário. Você pode pegar o código atualizado &lt;a href="https://ellie-app.com/88hPGjDDCHpa1"&gt;neste link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Percebeu que a moeda de destino está exibindo "Dólar americano" quando deveria estar exibindo o valor que está na model ("Euro")? Isso acontece porque não estamos utilizando a model nos valores dos inputs. Vamos corrigir isso agora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-- primeiro vamos importar o atributo "selected"
- import Html.Attributes exposing (class, type_, value)
&lt;/span&gt;&lt;span class="gi"&gt;+ import Html.Attributes exposing (class, type_, value, selected)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;            , form [ class "bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" ]
                [ div [ class "mb-4" ]
                    [ label [ class "block text-gray-700 text-sm font-bold mb-2" ]
                        [ text "Moeda de origem" ]
                    , div [ class "relative" ]
                        [ select
&lt;span class="gd"&gt;-                           [ class selectClasses ]
-                           [ option [ value "BRL"] [ text "Real" ] 
-                           , option [ value "USD"] [ text "Dólar americano" ]
-                           , option [ value "EUR"] [ text "Euro" ]
&lt;/span&gt;&lt;span class="gi"&gt;+                           [ class selectClasses, value model.from ]
+                           [ option [ value "BRL", selected (model.from == "BRL") ] [ text "Real" ]
+                           , option [ value "USD", selected (model.from == "USD") ] [ text "Dólar americano" ]
+                           , option [ value "EUR", selected (model.from == "EUR") ] [ text "Euro" ]
&lt;/span&gt;                            ]
                        ]
                    ]
                , div [ class "mb-4" ]
                    [ label [ class "block text-gray-700 text-sm font-bold mb-2" ]
                        [ text "Moeda de destino"
                        ]
                    , div [ class "relative" ]
                        [ select
&lt;span class="gd"&gt;-                           [ class selectClasses ]
-                           [ option [ value "USD"] [ text "Dólar americano" ]
-                           , option [ value "BRL"] [ text "Real" ]
-                           , option [ value "EUR"] [ text "Euro" ]
&lt;/span&gt;&lt;span class="gi"&gt;+                           [ class selectClasses, value model.to ]
+                           [ option [ value "USD", selected (model.to == "USD") ] [ text "Dólar americano" ]
+                           , option [ value "BRL", selected (model.to == "BRL") ] [ text "Real" ]
+                           , option [ value "EUR", selected (model.to == "EUR") ] [ text "Euro" ]
&lt;/span&gt;                            ]
                        ]
                    ]
                , div [ class "mb-6" ]
                    [ label [ class "block text-gray-700 text-sm font-bold mb-2" ]
                        [ text "Quantidade"
                        ]
&lt;span class="gd"&gt;-                   , input [ type_ "number", class "shadow appearence-none border rounded w-full py-2 px-3 text-gray" ] []
&lt;/span&gt;&lt;span class="gi"&gt;+                   , input [ type_ "number", value (String.fromFloat model.amount), class "shadow appearence-none border rounded w-full py-2 px-3 text-gray" ] []
&lt;/span&gt;                    ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Uma rápida explicação
&lt;/h3&gt;

&lt;p&gt;O atributo &lt;code&gt;selected&lt;/code&gt; precisa que seu parâmetro seja um valor boleano, então para conseguir esse valor boleano, verificamos se o valor selecionado na model é o mesmo que o valor da &lt;code&gt;option&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BRL"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BRL"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;No Elm, fazemos comparação de valores utilizando &lt;code&gt;==&lt;/code&gt; (dois sinais de igualdade). Agora no &lt;code&gt;input&lt;/code&gt; de quantidade, utilizamos a função &lt;code&gt;String.fromFloat&lt;/code&gt; pois o atributo &lt;code&gt;value&lt;/code&gt; precisa que seu parâmetro seja do tipo &lt;code&gt;string&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromFloat&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora quando clicar-mos para compilar, todos os valores deverão ser exibidos corretamente:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VdOBqPDW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/3f532ae116fc3ee7e21a90c366837601/c83ae/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VdOBqPDW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.fidelisclayton.dev/static/3f532ae116fc3ee7e21a90c366837601/c83ae/image-3.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Vou encerrar a parte 2 por aqui para que não fique muito extenso. Leve o tempo que precisar para entender o que aprendemos nesse tutorial. Hoje você aprendeu conceitos muito importantes (The Elm Architecture, funções e records) e que serão utilizados com muita frequência daqui pra frente.&lt;/p&gt;

&lt;p&gt;No próximo tutorial vamos (finalmente) adicionar a lógica para calcular a conversão das moedas. O código final dessa parte está disponível &lt;a href="https://ellie-app.com/88hXjYRzqbwa1"&gt;neste link&lt;/a&gt; e basta &lt;a href="https://www.fidelisclayton.dev/20200304-elm-na-pratica-3"&gt;clicar aqui&lt;/a&gt; para iniciar o próximo tutorial.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>functional</category>
    </item>
    <item>
      <title>Elm na prática - Imports, variáveis e o módulo HTML</title>
      <dc:creator>Clayton Fidelis</dc:creator>
      <pubDate>Tue, 03 Mar 2020 16:29:45 +0000</pubDate>
      <link>https://dev.to/fidelisclayton/elm-na-pratica-imports-variaveis-e-o-modulo-html-197h</link>
      <guid>https://dev.to/fidelisclayton/elm-na-pratica-imports-variaveis-e-o-modulo-html-197h</guid>
      <description>&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parte 1&lt;/strong&gt;: &lt;strong&gt;Imports, variáveis e o módulo HTML&lt;/strong&gt; (Você está aqui)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 2&lt;/strong&gt;: &lt;a href="https://www.fidelisclayton.dev/20200304-elm-na-pratica-2"&gt;The Elm Architecture, Records, funções e exibindo dados da Model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 3:&lt;/strong&gt; &lt;a href="https://www.fidelisclayton.dev/20200304-elm-na-pratica-3"&gt;Events, Pattern Matching, Maybe, Dict e implementando a lógica do conversor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 4&lt;/strong&gt;: &lt;em&gt;Type Signatures e adicionando tipos à nossa aplicação (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 5&lt;/strong&gt;: &lt;em&gt;Http, Commands, Browser.element e utilizando dados de uma API (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 6&lt;/strong&gt;: &lt;em&gt;Pipe e HttpBuilder (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 7&lt;/strong&gt;: &lt;em&gt;Configurando o ambiente de desenvolvimento local (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 8&lt;/strong&gt;: &lt;em&gt;Utilizando ports e flags (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 9&lt;/strong&gt;: &lt;em&gt;Trabalhando com rotas (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parte 10&lt;/strong&gt;: &lt;em&gt;Adicionando testes (não publicado)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://elm-lang.org/"&gt;Elm&lt;/a&gt; é uma linguagem de programação para front-end que chama muita atenção por prometer não causar erros em tempo de execução, isso é possível por quê ela é uma linguagem fortemente tipada. Além disso, ela possui um compilador extremamente sofisticado e super útil que vai nos ajudar bastante no desenvolvimento.&lt;/p&gt;

&lt;p&gt;No começo, a sintaxe parece ser bizarra, e caso você nunca tenha utilizado uma linguagem funcional vai se deparar com vários novos conceitos para aprender: funções puras, imutabilidade, monads e muitas outras coisas, mas posso te contar um segredo? Você não precisa entender tudo isso para começar a por a mão na massa. Apesar de parecer muita coisa, o que nos faz criar uma certa "resistência" ao tentar aprender a linguagem é o fato dela ser totalmente diferente das outras soluçōes mais utilizadas no mercado atualmente, mas te garanto que ela é bem mais simples do que parece. &lt;/p&gt;

&lt;p&gt;Nesta série de tutoriais, vamos quebrar essa barreira, pretendo te passar tudo que eu sei e da forma mais compreensível possível. Para isso, vamos construir uma aplicação do zero sem perder horas e horas tentando entender cada um dos conceitos citados anteriormente, o importante agora é praticar e sentir os benefícios que a linguagem tem a oferecer.&lt;/p&gt;

&lt;p&gt;Iremos construir uma aplicação bem simples mas que vai além do exemplo de contador que encontramos na documentação oficial, iremos codificar um simples conversor de moedas, mas que com ele aprenderemos todo o básico do Elm. Vamos aprender a usar condicionais, exibir elementos no navegador, reagir a ações do usuário, coletar texto de formulários. Começaremos utilizando apenas o básico e no decorrer da série iremos utilizar novas tecnicas e novas formas de solucionar os problemas.&lt;/p&gt;

&lt;p&gt;A aplicaçāo terá basicamente uma funcionalidade, usuário ira escolher uma moeda de origem, informará o quanto ele quer converter, nos dirá qual será a moeda de destino e então nossa aplicação fará a conversão. Vamos começar utilizando valores estáticos para as moedas mas no decorrer dessa série iremos aprender a como pegar dados de APIs e utilizá-los.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ambiente de desenvolvimento
&lt;/h3&gt;

&lt;p&gt;Por enquanto não vamos instalar nada no nosso computador, desenvolveremos tudo no navegador utilizando o &lt;a href="https://ellie-app.com/"&gt;Ellie App&lt;/a&gt;, uma IDE para Elm diretamente no browser. Para acessar a IDE, basta clicar &lt;a href="http://ellie-app.com/"&gt;neste link&lt;/a&gt;. No decorrer da série vamos instalar tudo na nossa máquina, apesar do processo não ser um bixo de 7 cabeças preferi postergar ele para quando estiver-mos mais familiarizados com a linguagem.&lt;/p&gt;

&lt;p&gt;Caso você se depare com uma mensagem antes de aparecer o editor de texto, basta clicar no botão  "&lt;strong&gt;Accept terms&lt;/strong&gt;" que em seguida ele será exibido:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dXFSwVBG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/idmgqj4idx6zwvlxbdtm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dXFSwVBG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/idmgqj4idx6zwvlxbdtm.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No canto superior esquerdo temos o editor de código Elm, abaixo dele, o editor de código HTML e na direita podemos visualizar o resultado ou, caso tenhamos algum erro, as mensagens do compilador (spoiler: são incríveis). Ah, importante lembrar que o editor salva seu código na nuvem, e para não perder ele, lembre de salvar o link caso você vá fechar o navegador, e o link muda cada vez que você salva o código. No decorrer da serie vamos aprender a configurar o ambiente no nosso proprio computador. Agora chega de conversa e vamos colocar a mão no código.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mão na massa
&lt;/h3&gt;

&lt;p&gt;Antes de tudo, vamos apagar todo o código que esta no editor de código Elm. Vamos começar com o clássico Hello World, só pra ver a coisa funcionando, talvez pareça estranho a primeira vista, mas garanto que jaja tudo vai fazer sentido.&lt;/p&gt;

&lt;p&gt;Digite (ou cole) o codigo a seguir e clique no botão "Compile" para vermos nosso primeiro Hello World:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Da2heNXK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b44a3f68jfbv3wmw8k07.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Da2heNXK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b44a3f68jfbv3wmw8k07.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Na &lt;strong&gt;primeira linha&lt;/strong&gt; definimos o nome do Módulo e o que vamos expor desse modulo. No Elm, é obrigatório definir o módulo na primeira linha do arquivo. Os valores dentro dos parêntesis após a palavra &lt;code&gt;exposing&lt;/code&gt; ficarão disponíveis para que outros módulos possam importar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Na &lt;strong&gt;terceira linha&lt;/strong&gt; informamos que queremos usa o pacote &lt;code&gt;Html&lt;/code&gt;, e dentro desse pacote eu quero o valor &lt;code&gt;text&lt;/code&gt;. A sintaxe não é muito familiar, então vamos entender melhor, existem 3 maneiras de importar um módulo no Elm:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Importando o módulo&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Importando dessa maneira, teremos que utilizar o nome do pacote como &lt;em&gt;namespace&lt;/em&gt; para chamar seus valores e funções, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;
&lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;
&lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Importando o módulo expondo seus valores e/ou funções&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Importando dessa maneira, podemos utilizar as funções e valores diretamente, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;span class="n"&gt;div&lt;/span&gt;
&lt;span class="n"&gt;span&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Importando um módulo e expondo todos os seus valores e funções&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Por último temos uma forma de exportar todos os valores e funções de um módulo de uma só vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Dessa forma, ao invés de deixar explícito quais itens do módulo nós queremos, utilizamos o &lt;code&gt;..&lt;/code&gt; (dois pontos) para informar que queremos tudo desse módulo. E podemos utilizar os valores igual a forma #2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora voltando ao exemplo, &lt;strong&gt;na linha 5&lt;/strong&gt; criamos uma variável com o nome &lt;code&gt;main&lt;/code&gt;, com isso, o Elm sabe que a aplicação vai ser inicializada por essa função.&lt;/p&gt;

&lt;p&gt;E por fim, na linha 6, utilizamos a função &lt;code&gt;text&lt;/code&gt; do pacote &lt;code&gt;Html&lt;/code&gt; para renderizar a mensagem "Hello World" na página, perceba que no Elm, não utilizamos parênteses para executar funcões, basta digitar o nome da função e em seguida informar os valores para seus parâmetros, nesse caso, uma string.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entendendo o módulo HTML
&lt;/h3&gt;

&lt;p&gt;Agora que já sabemos como importar módulos, suas funcões e como executá-las, vamos dar um passo adiante e entender como o módulo HTML do Elm funciona.&lt;/p&gt;

&lt;p&gt;O pacote HTML, como o próprio nome já diz, é responsável por renderizar as tags HTMLs no navegador. Agora vamos tentar utilizar algumas tags, até o momento só utilizamos a função &lt;code&gt;text&lt;/code&gt; que só serve para renderizar textos.&lt;/p&gt;

&lt;p&gt;Vamos tentar utilizar a tag &lt;code&gt;div&lt;/code&gt;, como já sabemos, precisamos importar essa função do pacote HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-import Html exposing (text)
&lt;/span&gt;&lt;span class="gi"&gt;+import Html exposing (text, div)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;E agora vamos utilizar ela lá no &lt;code&gt;main&lt;/code&gt; do nosso código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Clique em "Compile" e veremos o que vai acontecer...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Aq5cqhMl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tw0j4p541v8ih04ozocs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Aq5cqhMl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tw0j4p541v8ih04ozocs.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Parece que não deu certo. Agora conhecemos o &lt;strong&gt;Elm Compiler&lt;/strong&gt;, uma das melhores features da linguagem. O que vimos no lado direito foi um erro de compilação, nesse caso ocorreu por quê a função &lt;code&gt;div&lt;/code&gt; não está esperando uma &lt;code&gt;string&lt;/code&gt; como primeiro parâmetro, mas uma lista de atributos. Como sabemos disso? O compilador nos diz tudo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Entendo as mensagens de erro do compilador
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CkvumsNB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1qfmb3z2n43xoxtk9u81.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CkvumsNB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1qfmb3z2n43xoxtk9u81.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa é uma mensagem de erro do compilador do Elm, bem diferente do que estamos acostumados não é? Agora vamos dissecar essa mensagem de erro.&lt;/p&gt;

&lt;p&gt;Na &lt;strong&gt;primeira linha&lt;/strong&gt; temos o tipo de erro ocorreu, no caso é um &lt;strong&gt;Type Mismatch&lt;/strong&gt; (incompatibilidade de tipos).&lt;/p&gt;

&lt;p&gt;Na &lt;strong&gt;segunda linha&lt;/strong&gt; o compilador nos diz em qual linha o erro ocorreu, no caso, &lt;strong&gt;linha 6 e coluna 6&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A partir da &lt;strong&gt;terceira linha&lt;/strong&gt; o compilador nos dá mais detalhes de uma forma bem amigável e detalhada sobre o que está errado, perceba que o compilador se comunica da mesma forma que uma pessoa que estivesse ao seu lado falaria.&lt;/p&gt;

&lt;p&gt;Agora que já sabemos que o primeiro argumento da função &lt;code&gt;div&lt;/code&gt; é uma lista de atributos (&lt;code&gt;style&lt;/code&gt;, &lt;code&gt;class&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;src&lt;/code&gt;, &lt;code&gt;href&lt;/code&gt; usaremos eles em breve.) vamos tentar novamente passando uma lista vazia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora clique para compilar (🤞)... Outro erro:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--plNTP6Y9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jcllccvxzgo6r1cjl16l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--plNTP6Y9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jcllccvxzgo6r1cjl16l.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bom, o tipo do erro é o mesmo do anterior (Type Mismatch). Agora o compilador nos diz que o segundo argumento da função &lt;code&gt;div&lt;/code&gt; é do tipo &lt;code&gt;String&lt;/code&gt; (de fato é) mas a &lt;code&gt;div&lt;/code&gt; precisa que o segundo argumento seja &lt;code&gt;List (Html.Html msg)&lt;/code&gt;, uma lista de html.&lt;/p&gt;

&lt;p&gt;Agora tentaremos de novo passando como segundo argumento uma lista de HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Clique para compilar, dessa vez vai funcionar. Mas aparentemente nada mudou né? Bom, visualmente o resultado é o mesmo, mas vamos inspecionar o HTML para notarmos a diferença:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rW9BNPVx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1pztqaar1aqdvf9ci3ex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rW9BNPVx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1pztqaar1aqdvf9ci3ex.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reparou que agora o texto "Hello world" está dentro de uma tag &lt;code&gt;div&lt;/code&gt;? Pois é, é isso que o pacote HTML faz, transforma nosso código Elm em tags HTML que podem ser renderizadas no browser. Agora vamos trocar a &lt;code&gt;div&lt;/code&gt; para um botão só para ter certeza que um botão irá aparecer:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FtQH4mwX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n2454fknxh1hwgo63pbt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FtQH4mwX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n2454fknxh1hwgo63pbt.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Utilizando atributos HTML
&lt;/h4&gt;

&lt;p&gt;Lembra que o primeiro parâmetro de uma tag HTML no Elm é uma lista de atributos? Então vamos aprender a utilizá-los agora.&lt;/p&gt;

&lt;p&gt;Podemos importar os atributos através do pacote &lt;code&gt;Html.Attributes&lt;/code&gt;, vou utilizar o atributo &lt;code&gt;style&lt;/code&gt; como exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Para adicionar mais atributos, basta separá-los com virgulas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background-color"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello-world"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Combinando várias tags HTML
&lt;/h4&gt;

&lt;p&gt;Como já vimos anteriormente, o segundo parâmetro das tags HTML é uma lista de outras tags HTML, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello "&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;World"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Com excessão da função &lt;code&gt;text&lt;/code&gt;, todas as tags to pacote Html recebem os mesmos tipos como parâmetro: Primeiro uma lista de atributos (do pacote Html.Attributes) e uma lista de outras tags.&lt;/p&gt;

&lt;h4&gt;
  
  
  Criando o HTML da nossa aplicação
&lt;/h4&gt;

&lt;p&gt;Agora que já sabemos utilizar o pacote HTML, vamos dar uma acelerada e criar o esqueleto da nossa aplicação:&lt;/p&gt;

&lt;p&gt;Primeiro, vou mudar o import do Html para que possamos utilizar tudo dele e alguns atributos que também vamos precisar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- import Html exposing (div, span, text)
&lt;/span&gt;&lt;span class="gi"&gt;+ import Html exposing (..)
+ import Html.Attributes exposing(value, type_, class)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Em seguida vou adicionar o novo código da funçāo &lt;code&gt;main&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;main =
&lt;/span&gt;    div
&lt;span class="gd"&gt;-       [ span [ style "color" "blue" ] [ text "Hello " ]
-       , span [ style "color" "green" ] [ text "World" ]
-       ]
&lt;/span&gt;&lt;span class="gi"&gt;+        [ div []
+           [ h1 [] [ text "Conversor de Moedas" ]
+           , form []
+               [ div []
+                   [ label []
+                       [ text "Moeda de origem" ]
+                   , div []
+                       [ select []
+                           [ option [ value "BRL" ] [ text "Real" ]
+                           , option [ value "USD" ] [ text "Dólar americano" ]
+                           , option [ value "EUR" ] [ text "Euro" ]
+                           ]
+                       ]
+                   ]
+               , div []
+                   [ label [] [ text "Moeda de destino" ]
+                   , div []
+                       [ select []
+                           [ option [ value "USD" ] [ text "Dólar americano" ]
+                           [ option [ value "BRL" ] [ text "Real" ]
+                           , option [ value "EUR" ] [ text "Euro" ]
+                           ]
+                       ]
+                   ]
+               , div []
+                   [ label [] [ text "Quantidade" ]
+                   , input [ type_ "number" ] []
+                   ]
+               , div [] [ button [] [ text "Converter" ] ]
+               ]
+           ]
&lt;/span&gt;       ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Então o código final ficará assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type_&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Conversor de Moedas"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Moeda de origem"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BRL"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Real"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dólar americano"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EUR"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Euro"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Moeda de destino"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dólar americano"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BRL"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Real"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EUR"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Euro"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Quantidade"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;type_&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                    &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Converter"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;O código ainda está um pouco confuso né? Nada de pânico, isso é normal, com o tempo nos, apenas lembre do que aprendemos anteriormente, cada tag HTML recebe uma lista de atributos como primeiro parâmetro e uma lista de outras tags HTML como segundo parâmetro.&lt;/p&gt;

&lt;p&gt;Agora é só clicar para compilar para ver esse HTML em ação:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2fFrxXIu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8llrr4r12yrema5ev0i4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2fFrxXIu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8llrr4r12yrema5ev0i4.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Horrível né? Mas não vai ficar assim por muito tempo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utilizando bibliotecas CSS
&lt;/h3&gt;

&lt;p&gt;Para deixar o nosso app mais bonito e não perder muito tempo estilizando, vamos utilizar uma biblioteca CSS, hoje vou escolher a &lt;a href="https://tailwindcss.com/components"&gt;Tailwind CSS&lt;/a&gt;. Para isso vamos importar o CSS no arquivo HTML do projeto (o HTML fica na parte inferior esquerda do Ellie):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&lt;/span&gt;  &amp;lt;style&amp;gt;
&lt;span class="gi"&gt;+    body {
+      background-color: #edf2f7;
+    }
&lt;/span&gt;        /* you can style your program here */
  &amp;lt;/style&amp;gt;
&lt;span class="gi"&gt;+ &amp;lt;link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet"&amp;gt;
&lt;/span&gt;&lt;span class="gd"&gt;&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&lt;/span&gt;  &amp;lt;main&amp;gt;&amp;lt;/main&amp;gt;
  &amp;lt;script&amp;gt;
    var app = Elm.Main.init({ node: document.querySelector('main') })
    // you can use ports and stuff here
  &amp;lt;/script&amp;gt;
&lt;span class="gd"&gt;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Depois de adicionar o CSS, vamos utilizá-lo no nosso código Elm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type_&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center py-10"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;w-full max-w-xs"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-center text-2xl mb-6"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Conversor de Moedas"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mb-4"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block text-gray-700 text-sm font-bold mb-2"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Moeda de origem"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt;
                            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block appearance-none w-full border shadow py-2 px-3 pr-8 rounded"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BRL"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Real"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; 
                            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dólar americano"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EUR"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Euro"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; 
                            &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mb-4"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block text-gray-700 text-sm font-bold mb-2"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Moeda de destino"&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt;
                            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block appearance-none w-full border shadow py-2 px-3 pr-8 rounded"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dólar americano"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BRL"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Real"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; 
                            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EUR"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Euro"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; 
                            &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mb-6"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block text-gray-700 text-sm font-bold mb-2"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Quantidade"&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;type_&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shadow appearence-none border rounded w-full py-2 px-3 text-gray"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                    &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex w-full"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-blue-500 w-full hover:bg-blue-700 text-white font-bold py-2 px-4"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Converter"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora o nosso App parece estar um pouco mais bonito:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ANRfJjqd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mncz2qcl0amsshmy2civ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ANRfJjqd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mncz2qcl0amsshmy2civ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você não precisa entender essas classes CSS para esse tutorial, mas caso queira saber mais, da uma olhada na &lt;a href="https://tailwindcss.com/"&gt;documentação do Tailwind&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Aprendendo a criar variáveis
&lt;/h4&gt;

&lt;p&gt;Reparou que algumas tags possuem as mesmas classes? Para evitar duplicar código, vamos criar uma variável com esses valores.&lt;/p&gt;

&lt;p&gt;Primeiro vamos criar a variável &lt;code&gt;selectClasses&lt;/code&gt; que vai possuir as classes da tag &lt;code&gt;select&lt;/code&gt;, vamos colocá-la logo acima da função &lt;code&gt;main&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;selectClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block appearance-none w-full border shadow py-2 px-3 pr-8 rounded"&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;

&lt;span class="c1"&gt;-- restante do código&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Em seguida vamos substituir as &lt;code&gt;strings&lt;/code&gt;com o valor da nossa variável:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;div [ class "flex justify-center py-10" ]
&lt;/span&gt;        [ div [ class "w-full max-w-xs" ]
            [ h1 [ class "text-center text-2xl mb-6" ] [ text "Conversor de Moedas" ]
            , form [ class "bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" ]
                [ div [ class "mb-4" ]
                    [ label [ class "block text-gray-700 text-sm font-bold mb-2" ]
                        [ text "Moeda de origem" ]
                    , div [ class "relative" ]
                        [ select
&lt;span class="gd"&gt;-                           [ class "block appearance-none w-full border shadow py-2 px-3 pr-8 rounded" ]
&lt;/span&gt;&lt;span class="gi"&gt;+                           [ class selectClasses ]
&lt;/span&gt;                            [ option [ value "BRL" ] [ text "Real" ] 
                            , option [ value "USD" ] [ text "Dólar americano" ]
                            , option [ value "EUR" ] [ text "Euro" ] 
                            ]
                        ]
                    ]
                , div [ class "mb-4" ]
                    [ label [ class "block text-gray-700 text-sm font-bold mb-2" ]
                        [ text "Moeda de destino"
                        ]
                    , div [ class "relative" ]
                        [ select
&lt;span class="gd"&gt;-                           [ class "block appearance-none w-full border shadow py-2 px-3 pr-8 rounded" ]
&lt;/span&gt;&lt;span class="gi"&gt;+                           [ class selectClasses ]
&lt;/span&gt;                            [ option [ value "USD" ] [ text "Dólar americano" ]
                            , option [ value "BRL" ] [ text "Real" ] 
                            , option [ value "EUR" ] [ text "Euro" ] 
                            ]
                        ]
                    -- restante do código
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Vou encerrar esse tutorial por aqui, mas calma que ainda não acabou, ainda vamos dar vida a nossa aplicação. Você provavelmente ainda tem muita coisa para digerir, então o ideal é ir com calma. Antes de ir para o próximo tutorial, leve o tempo que precisar para entender e se familiarizar com o módulo HTML pois será essêncial ao decorrer dessa série.&lt;/p&gt;

&lt;p&gt;Não se preocupe caso sinta-se travado, é completamente normal, você provavelmente está saindo da sua zona de conforto aprendendo uma linguagem totalmente diferente, com sintaxe diferente e paradigma diferente, mas acredite em mim, você vai conseguir.&lt;/p&gt;

&lt;p&gt;Então é isso, você pode &lt;a href="https://www.fidelisclayton.dev/20200304-elm-na-pratica-2"&gt;clicar aqui para continuar para o próximo tutorial&lt;/a&gt;. O resultado final da parte 1 está disponível aqui: &lt;a href="https://ellie-app.com/88hp8WgJd5Ca1"&gt;https://ellie-app.com/88hp8WgJd5Ca1&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elm</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
