(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5LHNRP9'); thecodest, Autor em The Codest - Página 8 de 13

Introdução

Muitas vezes, é difícil manter o que não pode ser modificado. O padrão de embrulhar dados num contentor vem em seu socorro. Protege os valores para que o seu manuseamento seja seguro, excluindo os efeitos secundários.

Se é novo aqui, não se esqueça de ver as minhas duas últimas partes sobre programação funcional em The Codest blogue sobre:

Functor

Não tem uma lógica complexa. A sua principal tarefa é envolver o contexto e executar as funções que recebe do exterior. Cada vez que o valor muda, uma nova instância do contentor é reembalada e devolvida. Ao chamar o mapa que executa uma ação específica, devolve uma nova instância de contentor com o valor devolvido pela função passada, mantendo o princípio de não modificabilidade.

Declaração

 const Functor = value => ({
     map: fn => Functor(fn(value)),
     cadeia: fn => fn(valor),
     of: () => valor
 });

mapa - útil quando se pretende alterar o estado de um valor num contentor mas não se pretende devolvê-lo ainda.

cadeia - utilizado se quiser passar um valor para uma função sem modificar o estado do contentor. Geralmente no final de mapa chamadas.

de - devolver o valor atual

Exemplo imperativo

const randomInt = (max) => Math.floor(Math.random() * (max + 1))

const randomNumber = randomInt(200) // devolve um número entre 0 e 200

decrease(randomNumber) // devolve (número entre 0 e 200) - 1

Exemplo declarativo

const randomIntWrapper = (max) =>
Functor(max)
.map(increase) // max + 1
.map(multiplyBy(Math.random())) // Math.random() * (max + 1)
.map(Math.floor) // Math.floor(Math.random() * (max + 1))

const randomNumber = randomIntWrapper(200)

randomNumber.of() // devolve um número entre 0 e 200
randomNumber.chain(decrease) // devolve (número entre 0 e 200) - 1

Mónada

Por vezes, para além das funções que accionam o novo estado do valor, é necessária uma lógica adicional oculta no contentor. É aqui que a mônada se torna útil, pois é uma extensão de functor. Pode, por exemplo, decidir o que deve acontecer quando o valor tem um determinado valor ou qual o caminho que as próximas acções devem seguir.

Mónada Talvez

A mónada talvez resolva o problema dos valores que retornam não verdadeiros. Quando isso acontece, as mapa são ignoradas, mas permite-lhe devolver uma alternativa chamando o getOr método. Permite-lhe evitar a utilização de operadores if / else, que são populares em imperativo programação. Esta mónada é constituída por três contentores:

Nada - é executado quando um valor que não é verdadeiro cai no contentor ou filtro devolve falso. É utilizado para simular a execução de uma função. Isto significa que este contentor recebe a função mas não a executa.

- este é o contentor principal que executa todas as funções, mas se o valor mudar para um valor falso ou filtro retorna falso, ele passará para o método Nada contentor.

Talvez - Pego no valor inicial e decido qual o contentor a chamar no início.

Declaração

const Just = value => ({
map: fn => Maybe(fn(value)),
chain: fn => fn(value),
of: () => value,
getOr: () => valor,
filtro: fn => fn(valor) ? Just(value) : Nothing(),
type: 'just'
});

const Nothing = () => ({
map: fn => Nothing(),
chain: fn => fn(),
of: () => Nothing(),
getOr: substitute => substitute,
filter: () => Nothing(),
type: 'nothing'
});

const Maybe = valor =>
value === null || value === undefined || value.type === 'nothing'
? Nada()
: Just(value)
tabela métodos functor

Agora vamos construir o exemplo anterior sobre a condição. Se max for maior que zero, a função será executada. Caso contrário, retornará 0.

Exemplo imperativo

const randomInt = (max) => {
if(max > 0) {
return Math.floor(Math.random() * (max + 1))
} else {
return 0
}
}

const bookMiddlePage = 200

const randomPage = randomInt(10) || bookMiddlePage // devolve aleatório
const randomPage = randomInt(-10) || bookMiddlePage // devolve 200

Exemplo declarativo

const randomIntWrapper = (max) =>
Talvez(max)
.filter(max => max > 0) // o valor false ignora outras chamadas
.map(increase)
.map(multiplyBy(Math.random()))
.map(Math.floor)

const bookMiddlePage = 200

// Apenas contentor
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // retorna aleatório
// Contentor de nada
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // devolve 200


faixa de cooperação

pt_PTPortuguese