Conceitos de linguagens funcionais: uma breve introdução aos monads \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 02 Horas 

 29 Min 

 13 Seg 

   Tempo restante da oferta: 02 29 13 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Conceitos de linguagens funcionais: uma breve introdução aos monads  [ Desenvolvimento ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento) [ Programação funcional ](https://www.treinaweb.com.br/blog/categoria/programacao-funcional) 

# Conceitos de linguagens funcionais: uma breve introdução aos monads

 Neste post, dando continuidade à série sobre programação funcional, trataremos de um tema muito pertinente: os monads e suas definições essenciais.

 [ Cleber Campomori ](https://www.treinaweb.com.br/blog/autor/cleber-campomori) 8 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/04/08160716/capa-currying.jpg)  

O paradigma funcional vem ganhando cada vez mais espaço entre os desenvolvedores, quer seja pela sua naturalidade para lidar com problemas cada vez mais comuns em softwares de larga escala (como os aspectos de concorrência e paralelismo) ou por causa da sintaxe mais declarativa que as linguagens funcionais geralmente possuem. Mas, mesmo com essa popularização, o paradigma funcional ainda é visto com certo receio por uma série de razões, como a proximidade com a matemática (odiada por muitas pessoas) ou a grande quantidade de termos encarados como *obscuros* para quem não conhece o paradigma. Por isso, iniciei essa série de artigos abordando conceitos e termos típicos do paradigma funcional, tentando mostrar como as coisas podem ser muito mais simples do que parecem. [O primeiro artigo dessa série](https://www.treinaweb.com.br/blog/o-que-sao-as-linguagens-funcionais/ "O primeiro artigo dessa série") discute sobre os princípios mais essenciais do paradigma funcional. Já o segundo artigo, onde o *currying* é discutido, [pode ser acessado a partir daqui](https://www.treinaweb.com.br/blog/conceitos-de-linguagens-funcionais-o-que-e-currying/ "você pode acessá-lo a partir daqui"). Neste artigo, vamos discutir um pouco sobre um conceito essencial ao paradigma funcional: os *monads*.

### Relembrando alguns conceitos…

Antes de prosseguirmos aos *monads* de fato, vamos relembrar alguns pilares do paradigma funcional:

- O paradigma funcional tem forte inspiração nos conceitos relacionados às funções matemáticas;
- Um código escrito de maneira funcional é composto por funções que **sempre vão receber ao menos um parâmetro** e **produzir uma saída**;
- No paradigma funcional, as funções devem ser determinísticas, ou seja: dado um valor para um parâmetro, a saída produzida deve ser sempre a mesma em qualquer momento e situação. Por exemplo: se temos uma função `somar()` e esta função recebe os parâmetros `2`e `2`, esta função deve **sempre** retornar `4`, independente se ela for invocada hoje, amanhã, ano que vem ou no próximo milênio;
- Linguagens funcionais evitam o que é chamado *side effect* ou *transições de estado*: quando você cria uma “variável” (geralmente chamada de *binding* em programação funcional), esta “variável” não pode ter seu valor alterado em nenhuma circunstância. A grosso modo, é como se você estivesse trabalhando o tempo inteiro com “constantes de verdade”.

Sendo assim, vamos imaginar que necessitamos de alguma estrutura de código que execute uma operação de elevação de um número ao cubo… Se adotarmos o JavaScript como linguagem, poderíamos criar um “método” que executasse essa operação:

```javascript
const cubo = (n) => Math.pow(n, 3);

// Testes...
console.log(cubo(2)); // Resposta: 8

```

Por hora, tudo certo… Temos um trecho de código que segue todos os pilares do paradigma funcional. Também poderíamos ter uma função que calculasse a raiz quadrada de um número… O código seria bem similar:

```javascript
const raizQuadrada = (n) => Math.sqrt(n);

// Testes...
console.log(raizQuadrada(4)); // Resposta: 2

```

Por alguma razão, poderíamos precisar calcular a raiz quadrada de um número que foi elevado ao cubo… No caso acima, como ambas as funções recebem um parâmetro numérico e retornam um número, nós poderíamos encadear as chamadas destas funções, criando uma nova função como resultado da combinação das duas funções anteriores:

```javascript
const raizQuadrada = (n) => Math.sqrt(n);
const cubo = (n) => Math.pow(n, 3);

const raizQuadradaDoCubo = (n) => raizQuadrada(cubo(n));

// Testes...
console.log(raizQuadradaDoCubo(4)); // Resposta: 8 (4 elevado ao cubo = 64; raiz de 64 = 8)

```

Esse código ficaria mais interessante ainda se criássemos uma função que fosse responsável exclusivamente por realizar essa composição de funções… Poderíamos ter algo similar ao trecho de código abaixo:

```javascript
const juntar = (f, g) => (x) => f(g(x));

const cubo = (x) => Math.pow(x, 3);
const raizQuadrada = (x) => Math.sqrt(x);
const cuboDaRaizQuadrada = juntar(cubo, raizQuadrada);

// ...
console.log(cuboDaRaizQuadrada(4)); // Resultado: 8

```

[  ![F# (F Sharp) - Fundamentos](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/fsharp.svg)   Curso F# (F Sharp) - Fundamentos Conhecer o curso ](https://www.treinaweb.com.br/curso/fsharp-fundamentos)

O trecho de código acima implementa quase tudo que vimos sobre programação funcional: tudo está baseado em valores imutáveis, temos várias funções que recebem pelo menos um parâmetro e retornam um determinado valor relacionado ao processamento do parâmetro, as funções são todas determinísticas e até temos o *currying* em ação aqui, já que a função `juntar()` retorna uma outra função, que é o resultado da composição das funções `f()` e `g()`! E veja a estrutura declarativa do código: o código é fluído e fácil de ser lido… Mas esse código tem um problema crítico: o que aconteceria se passarmos `undefined` como argumento da função `cuboDaRaizQuadrada()`? Nesse caso, vamos acabar tendo o famoso `NaN`, o que é completamente errado. Podemos corrigir isso colocando uma verificação de segurança nas funções `cubo()` e `raizQuadrada()`:

```javascript
const juntar = (f, g) => (x) => f(g(x)); 

const cubo = (x) => {
  if (x) {
    return Math.pow(x, 3)
  } else {
    return 0;
  }
};

const raizQuadrada = (x) => {
  if (x) {
    Math.sqrt(x);
  } else {
    return 0;
  }
}

const cuboDaRaizQuadrada = juntar(cubo, raizQuadrada);

// ...
console.log(cuboDaRaizQuadrada(undefined)); // Resultado: 0

```

Isso resolve o nosso problema. Mas já temos código idêntico espalhado entre vários lugares… E cada nova função que implementássemos, precisaria replicar essa verificação. Essa situação é terrível, quer seja pela legibilidade (que já começa a ficar prejudicada), quer seja pela manutenibilidade desse trecho simples de código… Nós precisamos de uma estrutura que *encapsule* esse processo de verificação que necessitamos… E é aqui que começam a entrar os *monads*.

### Implementando o primeiro monad

Poderíamos escrever uma estrutura que encapsulasse esse valor e nos disesse se temos um valor válido em questão. Essa estrutura poderia ser definida da seguinte maneira:

```javascript
const _talvez = (valor) => ({
    valor,
    nada() {
      return valor == null || valor == undefined;
    }
});

const x = _talvez(4);
console.log(x.valor); // 4
console.log(x.nada()); // false
const y = _talvez(undefined);
console.log(y.valor); // undefined
console.log(y.nada()); // true

```

Agora, temos a estrutura `_talvez` que adiciona comportamentos ao objeto `valor`, fazendo com que seja possível:

- Encapsular o valor internamente, o expondo adequadamente através da propriedade `valor`;
- Tratar o valor que é encapsulado, o identificando como um valor válido ou não através da função `nada()`.

Essa é a definição mais essencial de um *monad*: uma estrutura que age como um *wrapper* em cima de um dado, expondo seu valor de maneira correta e controlando possíveis *side-effects* que sua manipulação pode causar (como o `NaN`que não esperávamos). Nossa estrutura `_talvez` ainda precisa implementar pelo menos mais uma funcionalidade para chegar mais próxima ainda da definição clássica de um *monad*: o encadeamento de operações no valor monádico. Ou seja: um *monad* precisa prover uma maneira de estabelecer uma sequência de operações que deve ser aplicada ao valor que ele guarda (em nosso exemplo, o valor contido em `valor` dentro da estrutura `_talvez`). Isso poderia ser implementado da seguinte maneira:

```javascript
const _talvez = (valor) => ({
    valor,
    nada() {
      return valor == null || valor == undefined;
    },
    ligar(fn) {
      if (this.nada()){
        return _talvez(null);
      } else {
        return _talvez(fn(this.valor));
      }
    }
});

```

[  ![Desenvolvedor Front-end Pleno](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/javascript.svg)   Formação Desenvolvedor Front-end Pleno Conhecer a formação ](https://www.treinaweb.com.br/formacao/desenvolvedor-front-end-pleno)

Veja que agora criamos mais uma função em nossa estrutura `_talvez`. A função `ligar()` recebe uma função que pode ser aplicada ao valor armazenado pela estrutura `_talvez`, desde que este seja considerado um valor válido (ou seja, que a função `nada()` retorne `false`). Se a função puder ser aplicada, um nova estrutura `_talvez` (ou seja, um novo *monad*) é gerado, permitindo a ligação com outras funções. Veja que, caso tenhamos um valor monádico inválido (ou seja, `nada()` retornar `true`), um novo *monad* também é gerado, mas com o valor `null`, já que temos um valor inválido. Isso é chamado de *automatic propagation*. Agora, podemos reescrever o nosso código que calcula a raiz de um número elevado ao cubo da seguinte forma, utilizando a nossa estrutura `_talvez`:

```javascript
const juntar = (f, g) => (x) => f(g(x)); 

const _talvez = (valor) => ({
    valor,
    nada() {
      return valor == null || valor == undefined;
    },
    ligar(fn) {
      if (this.nada()){
        return _talvez(null);
      } else {
        return _talvez(fn(this.valor));
      }
    }
});

const cubo = (monad) => monad.ligar(n => Math.pow(n, 3));
const raizQuadrada = (monad) => monad.ligar(n => Math.sqrt(n));
const cuboDaRaizQuadrada = juntar(cubo, raizQuadrada);

const x = _talvez(4);
console.log(cuboDaRaizQuadrada(x).valor); // 8
const y = _talvez(null);
console.log(cuboDaRaizQuadrada(y).valor); // null
const z = _talvez(undefined);
console.log(cuboDaRaizQuadrada(z).valor); // null

```

Veja que nosso *monad* evitou um possível side-effect (que poderia acontecer com o `NaN` que podia ser retornado), além de ainda seguir todos os princípios funcionais vistos anteriormente. Nossa estrutura `_talvez` é de fato bem próxima a um *monad*. Ah! Reparou a semelhança entre o método `ligar()` da estrutura `_talvez` com métodos comuns do JavaScript como o `map()`? Essa semelhança não acontece por acaso… Uma outra observação pertinente: se você já teve contato com alguma linguagem funcional (como F#, Haskell, Elixir, Scala, entre outras), vai também reparar que a nossa função `juntar()`, utilizada para compor funções, faz exatamente a mesma coisa que o *pipe operator* (`|>`) das linguagens funcionais. ;)

### Eu realmente preciso conhecer monads?

A resposta é… Depende. Se você não utiliza linguagens funcionais, não tem muito sentido estudar *monads*, tendo em vista que outros paradigmas (como o paradigma orientado a objetos) já quebram o conceito de *monads* só por se basearem em transições de estados. Eles podem até ajudar a reduzir a complexidade do código, mas outros paradigmas podem oferecer outras soluções mais interessantes através de outros *design patterns*. Se você utiliza alguma linguagem funcional, a resposta ainda é *depende*. Existem linguagens que implementam o conceito de maneira mais “suave” por considerar o conceito e o termo muito “agressivos” ou obscuros demais, escondendo algumas complicações do desenvolvedor (é o caso do F# por exemplo, que dá o nome de *workflow* e *computed expression* a estruturas similares aos *monads*). Outras linguagens já exibem os conceitos de *monads* de maneira bem explícita, como o Haskell. Com certeza será interessante para qualquer desenvolvedor que trabalhe com o paradigma funcional conhecer pelo menos os aspectos essenciais dos *monads*, mas a profundidade deste estudo fatalmente estará atrelada à linguagem utilizada. *Monads* constituem um conceito de fato mais complexo dentro do paradigma funcional. Tanto que ainda existem mais regras matemáticas que devem ser aplicadas para que determinada estrutura seja de fato considerada um *monad*. Mas, neste momento, não iremos entrar em uma discussão mais aprofundada sobre a definição dos *monads*. Porém, mesmo assim, não se trata de algo impossível ou mirabolante como o nome do termo pode sugerir: trata-se na verdade de uma estrutura poderosíssima que permite ao paradigma funcional continuar aplicando seus conceitos básicos em situações como no caso de imprevisibilidade de valores de entrada. De quebra, os *monads* ainda constituem um tipo de estrutura que não precisa necessariamente ficar restrita ao universo funcional, podendo ser aplicada até mesmo na programação orientada a objetos para encapsulamento de dados e simplificação de código.

- [ #Programação Funcional ](https://www.treinaweb.com.br/blog/tag/programacao-funcional)
- [ #Monads ](https://www.treinaweb.com.br/blog/tag/monads)
- [ #Maybe ](https://www.treinaweb.com.br/blog/tag/maybe)
- [ #Nothing ](https://www.treinaweb.com.br/blog/tag/nothing)
- [ #Just ](https://www.treinaweb.com.br/blog/tag/just)

Autor

 ![Cleber Campomori](//secure.gravatar.com/avatar/c659c6a58478cad5b7751370ba94205f?d=mm)

## Cleber Campomori

 Líder de Conteúdo/Inovação. Pós-graduado em Projeto e Desenvolvimento de Aplicações Web. Certificado Microsoft MCSD (Web). 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/cleber-campomori)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/functional-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     10 anos atrás

    ##  [ Imutabilidade de objetos no PHP ](https://www.treinaweb.com.br/blog/imutabilidade-de-objetos-no-php) 

     Imutabilidade é uma característica forte nas linguagens funcionais, onde a alteração de estado não é frequente e, quando ela acontece, é controlada. Veja como podemos ter objetos imutáveis no PHP.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/11/12132017/introducao-swoole-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Introdução ao Swoole, framework PHP assíncrono baseado em corrotinas ](https://www.treinaweb.com.br/blog/introducao-ao-swoole-framework-php-assincrono-baseado-em-corrotinas) 

     Uma Introdução ao Swoole, framework PHP assíncrono baseado em corrotinas e comparação dele com o modelo tradicional que usa um servidor web (nginx, apache etc) com PHP-FPM.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/10/15020508/rsz_bridge-246913_1920-400x280.png)  [ Orientação a Objetos ](https://www.treinaweb.com.br/blog/categoria/orientacao-a-objetos) 

     8 anos atrás

    ##  [ Os pilares da orientação a objetos ](https://www.treinaweb.com.br/blog/os-pilares-da-orientacao-a-objetos) 

     O paradigma orientado a objetos é um dos mais utilizados no mercado de trabalho. Neste artigo, veremos os pilares da orientação a objetos.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/web-2185247_640-400x280.jpg)  [ Web Services ](https://www.treinaweb.com.br/blog/categoria/web-services) 

     10 anos atrás

    ##  [ REST não é simplesmente retornar JSON: indo além com APIs REST ](https://www.treinaweb.com.br/blog/rest-nao-e-simplesmente-retornar-json-indo-alem-com-apis-rest) 

     Criar uma API REST não tem a ver com retornar JSON e sim com a correta utilização do protocolo HTTP.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/03/GUIA-LINGUAGEM-JAVA-400x280.png)  [ Java ](https://www.treinaweb.com.br/blog/categoria/java) 

     6 anos atrás

    ##  [ Guia da linguagem Java ](https://www.treinaweb.com.br/blog/guia-da-linguagem-java) 

     Confira neste guia os principais tópicos para iniciar seus estudos na linguagem Java.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/01/07093212/PYTHON-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     7 anos atrás

    ##  [ Afinal, por que devo aprender Python para 2020? ](https://www.treinaweb.com.br/blog/afinal-por-que-devo-aprender-python-para-2020) 

     Veja neste artigo os motivos para aprender Python neste ano de 2020.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/07/DICAS-ENTREVISTA-TI-400x280.png)  [ Carreira ](https://www.treinaweb.com.br/blog/categoria/carreira) 

     4 anos atrás

    ##  [ 5 dicas para entrevistas na área de TI ](https://www.treinaweb.com.br/blog/5-dicas-para-entrevistas-na-area-de-ti) 

     Depois de tanto se dedicar nos estudos, finalmente as empresas começaram a entrar em contato com você. Mas, agora, como funciona a parte das entrevistas? Como devo me preparar? Esta é a primeira parte do artigo de como se preparar para uma entrevista de TI.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/05/como-instalar-o-csharp-e-nosso-primeiro-exemplo-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     4 anos atrás

    ##  [ Orientação a objetos no C# ](https://www.treinaweb.com.br/blog/orientacao-a-objetos-no-csharp) 

     Aprenda como trabalhar com classes, atributos, métodos e objetos no C# e aumente seus conhecimentos nessa linguagem incrível!

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/05/01125223/react-php-imagem-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     8 anos atrás

    ##  [ Promises no ReactPHP ](https://www.treinaweb.com.br/blog/promises-no-reactphp) 

     Dando continuidade aos artigos sobre programação assíncrona com PHP, neste artigo veremos o componente do ReactPHP para trabalharmos com Promises.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/02/13190452/php-cloud-400x280.jpg)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Aplicação Serverless desenvolvida em PHP usando AWS Lambda ](https://www.treinaweb.com.br/blog/aplicacao-serverless-desenvolvida-em-php-usando-aws-lambda) 

     Veja como fazer o deploy de uma aplicação PHP Serverless no AWS Lambda usando o Bref.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/11/PROFISSIONAL-USABILIDADE-400x280.png)  [ Acessibilidade e User Experience (UX) ](https://www.treinaweb.com.br/blog/categoria/acessibilidade-e-user-experience-ux) 

     6 anos atrás

    ##  [ Como é o dia a dia de um profissional de Usabilidade? ](https://www.treinaweb.com.br/blog/como-e-o-dia-a-dia-de-um-profissional-de-usabilidade) 

     O profissional de usabilidade possui habilidades que mesclam aspectos técnicos e estratégicos. Ele é o responsável por analisar, medir e melhorar o nível de satisfação do usuário ao utilizar um site ou aplicativo.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/07/importancia-de-pensar-em-design-inclusivo-400x280.png)  [ Acessibilidade e User Experience (UX) ](https://www.treinaweb.com.br/blog/categoria/acessibilidade-e-user-experience-ux) 

     6 anos atrás

    ##  [ Importância de pensar em Design Inclusivo ](https://www.treinaweb.com.br/blog/importancia-de-pensar-em-design-inclusivo) 

     Conheça o que é design inclusivo, seus princípios e a importância de pensar em acessibilidade em seus produtos desde o início do projeto.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **02h 29min 13s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
