<commit_before>
\documentclass[10pt, conference]{IEEEtran}

\usepackage[numbers,sort&compress,square]{natbib}
\usepackage{listings}
\usepackage{lipsum}
\usepackage[T1]{fontenc}
\usepackage[portuguese]{babel}
\usepackage[utf8]{inputenc}
\usepackage{listings}
\usepackage[svgnames]{xcolor}
\usepackage{textcomp}
\usepackage{enumitem}
\usepackage{subcaption}
\usepackage{tikz}

\usetikzlibrary{matrix}

% configs listings
\renewcommand{\lstlistingname}{Listagem}
\lstset{
	basicstyle = \footnotesize\tt,
	breakatwhitespace = true,
	breaklines = true,
	captionpos = b,
	extendedchars = true,
	language = Java,
	frame = single,
	keywordstyle = \bf,
	showspaces = false,
	showstringspaces = false,
	showtabs = false,
	tabsize = 2,
	abovecaptionskip = 1em,
	belowcaptionskip = 1em,
	aboveskip = 2em,
    belowskip = 5pt,
    xleftmargin = 5pt,
	xrightmargin = 5pt
}

% configs footnotes
\renewcommand\footnoterule{\kern-3pt \hrule width 2in \kern 2.6pt}

\begin{document}
\bstctlcite{IEEEexample:BSTcontrol}

\title { 
	Category Theory \\
	Arrows e Monads \\
	em Java 
}

\author{

	\IEEEauthorblockN{ <NAME> }
	\IEEEauthorblockA{
		Ciências da Computação \\
		Centro Universitário La Salle - Unilasalle \\
		Email: <EMAIL>
	}

	\and	
	
	\IEEEauthorblockN { <NAME> }
	\IEEEauthorblockA { 
		Ciências da Computação \\
		Centro Universitário La Salle - Unilasalle \\
		Email: <EMAIL>
	}
}
					  
\maketitle

\thispagestyle{plain}
\pagestyle{plain}

\begin{abstract}

\textcolor{red}{<escrever>}

\end{abstract}

\begin{IEEEkeywords}

\textcolor{red}{<escrever>}

\end{IEEEkeywords}

\section{INTRODUÇÃO}
\label{sec:intro}

<escrever>

\section{SOBRE O PARADIGMA FUNCIONAL}
\label{sec:func-para}
Influenciado principalmente pelo desenvolvimento do lambda calculus~\cite{hudak1989conception}, compondo o grupo da programação declarativa, o paradigma funcional utiliza-se da ideia de expressar computações através de funções combinadas em expressões. Neste, funções determinam o que deverá ser computado, ao invés de como sera computado~\cite{louden2011programming}. Programas são construídos através da composição, tal que funções triviais (building blocks) são combinadas dando origem a novas funções que descrevem computações mais complexas.

Building blocks não devem fazer uso de variáveis que dependam de estado, isso significa que a computação deve ser pura e sem efeitos colaterais (side-effects). Também destaca-se o princípio de imutabilidade, onde o valor de uma variável é determinado em sua criação, não permitindo novas atribuições posteriormente. Ao expressar um programa em uma linguagem funcional obtém-se uma maneira concisa de solucionar problemas, sendo que este constitui-se de operações e objetos atômicos e regras gerais para sua composição~\cite{michaelson2011introduction}.

Tais propriedades são apreciadas nos tempos atuais, visto que a Lei de Moore nos fornece cada vez mais núcleos, não necessariamente núcleos mais rápidos~\cite{jsr335}. Em programas não-determinísticos, múltiplas threads podem alterar os dados representados por objetos imutáveis sem ocasionar os diversos problemas já conhecidos como dead locks e race conditions. Além do thread safety oferecido pela propriedade de imutabilidade, o conceito de funções transparentes referencialmente, ou seja, funções que não utilizam variáveis de estado, também oferecem vantagens para a concorrência com múltiplas threads podendo invocar tais funções esperando sempre o mesmo retorno, dados os mesmos argumentos.

Na última década muitos problemas encontrados -- como enviar não só dados, mas também comandos através de redes -- já foram solucionados em linguagens que suportam o paradigma funcional~\cite{fischer2015java}. Assim, linguagens multi-paradigma têm adicionado suporte à estas mesmas estruturas, aumentando sua flexibilidade e ganho para com os desenvolvedores. O suporte a lambda expressions em Java não tem como objetivo apenas substituir Anonymous Inner Classes, mas também ser capaz de trazer os benefícios deste paradigma ao ponto de incrementar o ecossistema da linguagem.

\subsection{Lambda Expressions e Anonymous Inner Classes}
Ao fornecer suporte a funções de primeira classe, também chamadas de lambda expressions ou closures~\footnote{Lambda expressions ou closures são funções que não exigem vínculos de classe, como exemplo podendo ser atribuída a uma variável. Com esta caraterística, uma função atua como dado, ou seja, pode ser passada como argumento para outras funções.}, a linguagem Java habilita a substituição de annonymous inner classes (AIC) de forma transparente. Conforme a listagem~\ref{lst:array-aic-sort}, em Java a ordenação de inteiros pode ser implementada a partir de uma AIC em conjunto do método sort da classe Arrays.

\begin{lstlisting}[caption={Sort - Anonymous Inner Class}, label={lst:array-aic-sort}]
Integer[] integers = new Integer[]{5, 4, 3, 2, 1};

Arrays.sort(integers, new Comparator<Integer>() {
    public int compare(Integer a, Integer b) {
        return a.compareTo(b);
    }
});
\end{lstlisting}

Neste trecho de código o método \textit{sort} recebe como primeiro argumento um array de inteiros (já declarado na variável \textit{integers}) e como segundo qualquer instância que satisfaça o contrato de \textit{Comparator}. Assim, para satisfazer o segundo argumento, instância-se uma AIC através da palavra reservada \textbf{new} que implementa o método \textit{compare} declarado no contrato.

Entretanto, com closures o mesmo método \textit{sort} pode ter seus argumentos simplificados. Conforme demonstrado na listagem~\ref{lst:array-lambda-sort}, ao invés de instanciar uma AIC, uma lambda expression é passada como segundo argumento, removendo a necessidade de instanciação de uma classe e a implementação de um contrato imposto por \textit{Comparator}.

\begin{lstlisting}[caption={Sort - Lambda Expression}, label={lst:array-lambda-sort}]
Arrays.sort(integers, (a, b) -> a.compareTo(b));
\end{lstlisting}

De fato, apesar de expressarem o mesmo comportamento a nível de código, ambas funcionalidades possuem diferentes implementações sob a Máquina Virtual Java (JVM). AIC são compiladas, ou seja, geram novos arquivos contendo declarações de classes. Além do mais, ao utilizar a palavra reservada \textbf{this} referencia-se a própria instância anônima. Como representam instâncias de uma classe, estas devem ser carregadas pelo classloader e seus construtores invocados pela máquina virtual. Ambas etapas consomem memória, tanto heap~\cite{hunt2011java} para alocação de objetos quanto permgem\footnote{Área de memória limitada separada da heap chamada Permanent Generation que possui a função de armazenar objetos de geração permanente como metadados, classes e métodos.}.

Diferentemente de AIC, lambdas postergam a estratégia de compilação para em tempo de execução, utilizando a instrução invokedynamic~\cite{goetz2012translation}. Funções são traduzidas para métodos estáticos vinculados ao arquivo da classe correspondente a sua declaração, eliminando o consumo de memória. Agora, ao referir-se a \textbf{this}, a classe que delimita a lamda expression é acessada, ao contrário de AIC que acessa sua própria instância.

Além destes benefícios, lambda expressions possibilitam a implementação de novas bibliotecas que trazem consigo as propriedades do paradigma funcional. São suficientemente poderosas para expressar as mesmas construções, sem os encargos impostos pelas antigas implementações. Além disso, a adoção do paradigma funcional torna os usuários aptos a aderirem a novas estruturas advindas da Category Theory, como a classe \textit{Optional}, disponível na última versão da linguagem.

\section{CATEGORY THEORY E SUAS ESTRUTURAS}
A Category Theory (CT) foi inventada no início dos anos 1940 por <NAME> e <NAME>~\cite{eilenbergmaclane1945naturalequivalences} como uma ponte entre os diferentes campos da topologia e álgebra~\cite{spivak2014cts}. Afim de demonstrar as relações entre estruturas e sistemas matemáticos~\cite{maclane1971mat}, a CT estabelece uma linguagem formal capaz de encontrar aplicabilidade em várias áreas da ciência. Tal como Group Theory\footnote{A Group Theory estuda as estruturas algébricas chamadas Group. Um Group é um conjunto de elementos finito ou infinito associado a uma operação binária, como por exemplo a adição ou multiplicação.} abstrai a ideia do sistema de permutações como simetrias de um objeto geométrico, a CT manifesta-se como um sistema de funções entre conjuntos de objetos~\cite{awodey2010category}.

\begin{figure}[!h]
\centering
	\begin{tikzpicture}[baseline=-0.8ex]
    	\matrix (m) [
        	    matrix of math nodes,
            	row sep=3em,
	            column sep=5em,
				text height=2ex, text depth=0.5ex
            	] {
			A & B \\
			  & C \\
        };
    	\path[->]
        	(m-1-1) edge node[above] {$f$} (m-1-2)
			(m-1-2) edge node[right] {$g$} (m-2-2)
			(m-1-1) edge node[left = 0.9cm, below = 0.001cm] {$h =$ $g \circ f$} (m-2-2);
	\end{tikzpicture}
\caption{Sitema de funções e coleções de objetos}
\label{fig:f-g-composition}
\end{figure}

Conforme a figura~\ref{fig:f-g-composition}, os conjuntos de objetos são representado por $A$, $B$ e $C$. Nesta mesma estrutura, as funções $f$ e $g$ denotam os morfismos entre os diferentes conjuntos de objetos, tal que $f: A \rightarrow B$ e $g: B \rightarrow C$. A função $h$, definida por $h: A \rightarrow C$ dá-se como produto da composição de $f$ e $g$. A composição de funções, conforme a seção~\ref{sec:func-para} e expressa através de $h$ na figura~\ref{fig:f-g-composition}, firma uma ligação entre o paradigma funcional e a organização estrutural derivada da CT.

A partir desta ligação, Moggi em seus trabalhos \cite{moggi1989lambdaandmonads, mogi1991notionsofcompandmonad} introduziu o conceito de monad em Haskell. Este foi capaz de fornecer os mecanismos necessários para capacitar a solução de um dos problemas fundamentais da linguagem,  pertencente ao conjunto The Awkward Squad \cite{jones2001tacklingthe}. A partir de outros conceitos como functors, categories, arrows, o trabalho de Moggi foi incrementado criando novas estruturas que estão presentes nas versões mais recentes da linguagem.

\subsection{Category -- Objetos e Morfismos}

Uma category consiste em uma coleção de coisas, todas relacionadas de algum modo. As coisas são nomeadas de objetos e as relações de morfismos \cite{spivak2014cts}.\\

\textbf{Definição}: conforme \cite{spivak2014cts, maclane1971mat}, uma category $C$ é definida como:

\begin{enumerate}[label=(\alph*), leftmargin=3em, topsep = 0pt, itemsep = 1ex, partopsep = 1ex, parsep = 1ex]
	\item uma coleção $Ob(C)$, contendo os objetos de $C$;
	\item para cada par $a, b \in Ob(C)$, um conjunto $Hom_C(a, b)$ chamado de morfismos de $a$ para $b$;
	\item para cada objeto $a \in Ob(C)$, um morfismo de \textit{identidade} em $a$ denotado por $id_a \in Hom_C(x, a)$;
	\item para cada três objetos $a, b, c \in Ob(C)$, uma função de composição $\circ: Hom_C(b, c) \times Hom_C(a, b) \rightarrow Hom_C(a, c)$;
\end{enumerate}

Dado os objetos $a, b \in Ob(C)$, denota-se o morfismo $f \in Hom_C(a, b)$ por $f: a \rightarrow b$; onde $a$ é o domínio e $b$ o contradomínio.\\

Estas operações em $C$ devem satisfazer os seguintes axiomas:

\begin{enumerate}[label={}, leftmargin = 2em, topsep = 0pt, itemsep = 1ex,partopsep = 1ex, parsep = 1ex]
	\item \textit{(Identidade)} Para todo objeto $a, b \in Ob(C)$ e todo morfismo $f: a \rightarrow b$, tem-se $id_a \circ f = f = id_b \circ f$;
	\item \textit{(Associatividade)} Sejam os objetos $a, b, c, d \in Ob(C)$ e os morfismos $f: a \rightarrow b$, $g: b \rightarrow c$ e $h: c \rightarrow d$. Então $(h \circ g) \circ f = h \circ (g \circ f)$.
\end{enumerate}

\bigskip

Ambos axiomas podem ser representados pelos diagramas comutativos das figuras~\ref{fig:comut-ident} e \ref{fig:comut-assoc}.

\begin{figure}[h]
	\begin{minipage}[t]{.48\linewidth}
		\centering
			\begin{tikzpicture}[baseline=(current bounding box.north)]
				\matrix (m) [
							matrix of math nodes,
							row sep=3em,
							column sep=5em,
							text height=2ex, text depth=0.5ex
						]{
							a & a \\
							b & b \\
						};

					\path[->]
						(m-1-1) edge node[above] {$id_a$} (m-1-2)
						(m-1-1) edge node[left] {$f$} (m-2-1)
						(m-1-2) edge node[above] {$f$} (m-2-1)
						(m-1-2) edge node[right]  {$f$} (m-2-2)
						(m-2-1) edge node[above] {$id_b$} (m-2-2);
			\end{tikzpicture}
			\caption{Identidade}
			\label{fig:comut-ident}
	\end{minipage}
	\begin{minipage}[t]{.48\linewidth}
		\centering
			\begin{tikzpicture}[baseline=(current bounding box.north)]
				\matrix (m) [
							matrix of math nodes,
							row sep=3em,
							column sep=5em,
							text height=2ex, text depth=0.5ex
						] {
							a & b \\
							c & d \\
						};
					\path[->]
						(m-1-1) edge node[above] {$f$} (m-1-2)
						(m-1-1) edge node[left] {$g \circ f$} (m-2-1)
						(m-1-2) edge node[above] {$g$} (m-2-1)
						(m-1-2) edge node[right]  {$h \circ g$} (m-2-2)
						(m-2-1) edge node[above] {$h$} (m-2-2);
			\end{tikzpicture}
			\caption{Associatividade}
			\label{fig:comut-assoc}
	\end{minipage}
\end{figure}

\subsection{Functor -- Categories e Morfismos}

Um functor $F$ consiste em um morfismo entre duas categories \cite{maclane1971mat}. Estes morfismos, chamados homomorfismos, tem como característica a preservação de estrutura de $F$. Assim como categories, functors devem satisfazer os axiomas de associatividade e identidade.\\

\textcolor{red}{<adicionar notações matemáticas e diagramas>}

\subsection{Monad -- Endofunctor e Transformações Naturais}

Endofunctors equipados com as natural transformations unit e multiplication \cite{maclane1971mat} são chamados de monad. Define-se endofunctors como functors cujos morfismos dão-se em uma mesma category. Além disso, natural transformations são morfismos entre functors, tendo como principal característica a preservação de estrutura. Como todas as estruturas já mencionadas, monads também devem satisfazer as propriedades de associatividade e identidade.\\

\textcolor{red}{<adicionar notações matemáticas e diagramas comutativos>}

\subsection{Arrow -- Kleisli Triples}

A partir de um monad podemos construir kleisli triples. Podemos pensar em kleisli triples como uma outra forma de representar sintaticamente um monad. Similar a monads, estas também obedecem as propriedades de associatividade e comutatividade.\\

\textcolor{red}{<adicionar notações matemáticas e diagramas comutativos>}

\bibliographystyle{IEEEtran}
\bibliography{references}

\end{document}<commit_msg>Caption from Figura 2 was changed.<commit_after>
\documentclass[10pt, conference]{IEEEtran}

\usepackage[numbers,sort&compress,square]{natbib}
\usepackage{listings}
\usepackage{lipsum}
\usepackage[T1]{fontenc}
\usepackage[portuguese]{babel}
\usepackage[utf8]{inputenc}
\usepackage{listings}
\usepackage[svgnames]{xcolor}
\usepackage{textcomp}
\usepackage{enumitem}
\usepackage{subcaption}
\usepackage{tikz}

\usetikzlibrary{matrix}

% configs listings
\renewcommand{\lstlistingname}{Listagem}
\lstset{
	basicstyle = \footnotesize\tt,
	breakatwhitespace = true,
	breaklines = true,
	captionpos = b,
	extendedchars = true,
	language = Java,
	frame = single,
	keywordstyle = \bf,
	showspaces = false,
	showstringspaces = false,
	showtabs = false,
	tabsize = 2,
	abovecaptionskip = 1em,
	belowcaptionskip = 1em,
	aboveskip = 2em,
    belowskip = 5pt,
    xleftmargin = 5pt,
	xrightmargin = 5pt
}

% configs footnotes
\renewcommand\footnoterule{\kern-3pt \hrule width 2in \kern 2.6pt}

\begin{document}
\bstctlcite{IEEEexample:BSTcontrol}

\title { 
	Category Theory \\
	Arrows e Monads \\
	em Java 
}

\author{

	\IEEEauthorblockN{ <NAME> }
	\IEEEauthorblockA{
		Ciências da Computação \\
		Centro Universitário La Salle - Unilasalle \\
		Email: <EMAIL>
	}

	\and	
	
	\IEEEauthorblockN { <NAME> }
	\IEEEauthorblockA { 
		Ciências da Computação \\
		Centro Universitário La Salle - Unilasalle \\
		Email: <EMAIL>
	}
}
					  
\maketitle

\thispagestyle{plain}
\pagestyle{plain}

\begin{abstract}

\textcolor{red}{<escrever>}

\end{abstract}

\begin{IEEEkeywords}

\textcolor{red}{<escrever>}

\end{IEEEkeywords}

\section{INTRODUÇÃO}
\label{sec:intro}

<escrever>

\section{SOBRE O PARADIGMA FUNCIONAL}
\label{sec:func-para}
Influenciado principalmente pelo desenvolvimento do lambda calculus~\cite{hudak1989conception}, compondo o grupo da programação declarativa, o paradigma funcional utiliza-se da ideia de expressar computações através de funções combinadas em expressões. Neste, funções determinam o que deverá ser computado, ao invés de como sera computado~\cite{louden2011programming}. Programas são construídos através da composição, tal que funções triviais (building blocks) são combinadas dando origem a novas funções que descrevem computações mais complexas.

Building blocks não devem fazer uso de variáveis que dependam de estado, isso significa que a computação deve ser pura e sem efeitos colaterais (side-effects). Também destaca-se o princípio de imutabilidade, onde o valor de uma variável é determinado em sua criação, não permitindo novas atribuições posteriormente. Ao expressar um programa em uma linguagem funcional obtém-se uma maneira concisa de solucionar problemas, sendo que este constitui-se de operações e objetos atômicos e regras gerais para sua composição~\cite{michaelson2011introduction}.

Tais propriedades são apreciadas nos tempos atuais, visto que a Lei de Moore nos fornece cada vez mais núcleos, não necessariamente núcleos mais rápidos~\cite{jsr335}. Em programas não-determinísticos, múltiplas threads podem alterar os dados representados por objetos imutáveis sem ocasionar os diversos problemas já conhecidos como dead locks e race conditions. Além do thread safety oferecido pela propriedade de imutabilidade, o conceito de funções transparentes referencialmente, ou seja, funções que não utilizam variáveis de estado, também oferecem vantagens para a concorrência com múltiplas threads podendo invocar tais funções esperando sempre o mesmo retorno, dados os mesmos argumentos.

Na última década muitos problemas encontrados -- como enviar não só dados, mas também comandos através de redes -- já foram solucionados em linguagens que suportam o paradigma funcional~\cite{fischer2015java}. Assim, linguagens multi-paradigma têm adicionado suporte à estas mesmas estruturas, aumentando sua flexibilidade e ganho para com os desenvolvedores. O suporte a lambda expressions em Java não tem como objetivo apenas substituir Anonymous Inner Classes, mas também ser capaz de trazer os benefícios deste paradigma ao ponto de incrementar o ecossistema da linguagem.

\subsection{Lambda Expressions e Anonymous Inner Classes}
Ao fornecer suporte a funções de primeira classe, também chamadas de lambda expressions ou closures~\footnote{Lambda expressions ou closures são funções que não exigem vínculos de classe, como exemplo podendo ser atribuída a uma variável. Com esta caraterística, uma função atua como dado, ou seja, pode ser passada como argumento para outras funções.}, a linguagem Java habilita a substituição de annonymous inner classes (AIC) de forma transparente. Conforme a listagem~\ref{lst:array-aic-sort}, em Java a ordenação de inteiros pode ser implementada a partir de uma AIC em conjunto do método sort da classe Arrays.

\begin{lstlisting}[caption={Sort - Anonymous Inner Class}, label={lst:array-aic-sort}]
Integer[] integers = new Integer[]{5, 4, 3, 2, 1};

Arrays.sort(integers, new Comparator<Integer>() {
    public int compare(Integer a, Integer b) {
        return a.compareTo(b);
    }
});
\end{lstlisting}

Neste trecho de código o método \textit{sort} recebe como primeiro argumento um array de inteiros (já declarado na variável \textit{integers}) e como segundo qualquer instância que satisfaça o contrato de \textit{Comparator}. Assim, para satisfazer o segundo argumento, instância-se uma AIC através da palavra reservada \textbf{new} que implementa o método \textit{compare} declarado no contrato.

Entretanto, com closures o mesmo método \textit{sort} pode ter seus argumentos simplificados. Conforme demonstrado na listagem~\ref{lst:array-lambda-sort}, ao invés de instanciar uma AIC, uma lambda expression é passada como segundo argumento, removendo a necessidade de instanciação de uma classe e a implementação de um contrato imposto por \textit{Comparator}.

\begin{lstlisting}[caption={Sort - Lambda Expression}, label={lst:array-lambda-sort}]
Arrays.sort(integers, (a, b) -> a.compareTo(b));
\end{lstlisting}

De fato, apesar de expressarem o mesmo comportamento a nível de código, ambas funcionalidades possuem diferentes implementações sob a Máquina Virtual Java (JVM). AIC são compiladas, ou seja, geram novos arquivos contendo declarações de classes. Além do mais, ao utilizar a palavra reservada \textbf{this} referencia-se a própria instância anônima. Como representam instâncias de uma classe, estas devem ser carregadas pelo classloader e seus construtores invocados pela máquina virtual. Ambas etapas consomem memória, tanto heap~\cite{hunt2011java} para alocação de objetos quanto permgem\footnote{Área de memória limitada separada da heap chamada Permanent Generation que possui a função de armazenar objetos de geração permanente como metadados, classes e métodos.}.

Diferentemente de AIC, lambdas postergam a estratégia de compilação para em tempo de execução, utilizando a instrução invokedynamic~\cite{goetz2012translation}. Funções são traduzidas para métodos estáticos vinculados ao arquivo da classe correspondente a sua declaração, eliminando o consumo de memória. Agora, ao referir-se a \textbf{this}, a classe que delimita a lamda expression é acessada, ao contrário de AIC que acessa sua própria instância.

Além destes benefícios, lambda expressions possibilitam a implementação de novas bibliotecas que trazem consigo as propriedades do paradigma funcional. São suficientemente poderosas para expressar as mesmas construções, sem os encargos impostos pelas antigas implementações. Além disso, a adoção do paradigma funcional torna os usuários aptos a aderirem a novas estruturas advindas da Category Theory, como a classe \textit{Optional}, disponível na última versão da linguagem.

\section{CATEGORY THEORY E SUAS ESTRUTURAS}
A Category Theory (CT) foi inventada no início dos anos 1940 por <NAME> e <NAME>~\cite{eilenbergmaclane1945naturalequivalences} como uma ponte entre os diferentes campos da topologia e álgebra~\cite{spivak2014cts}. Afim de demonstrar as relações entre estruturas e sistemas matemáticos~\cite{maclane1971mat}, a CT estabelece uma linguagem formal capaz de encontrar aplicabilidade em várias áreas da ciência. Tal como Group Theory\footnote{A Group Theory estuda as estruturas algébricas chamadas Group. Um Group é um conjunto de elementos finito ou infinito associado a uma operação binária, como por exemplo a adição ou multiplicação.} abstrai a ideia do sistema de permutações como simetrias de um objeto geométrico, a CT manifesta-se como um sistema de funções entre conjuntos de objetos~\cite{awodey2010category}.

\begin{figure}[!h]
\centering
	\begin{tikzpicture}[baseline=-0.8ex]
    	\matrix (m) [
        	    matrix of math nodes,
            	row sep=3em,
	            column sep=5em,
				text height=2ex, text depth=0.5ex
            	] {
			A & B \\
			  & C \\
        };
    	\path[->]
        	(m-1-1) edge node[above] {$f$} (m-1-2)
			(m-1-2) edge node[right] {$g$} (m-2-2)
			(m-1-1) edge node[left = 0.9cm, below = 0.001cm] {$h =$ $g \circ f$} (m-2-2);
	\end{tikzpicture}
\caption{Funções entre coleções de objetos}
\label{fig:f-g-composition}
\end{figure}

Conforme a figura~\ref{fig:f-g-composition}, os conjuntos de objetos são representado por $A$, $B$ e $C$. Nesta mesma estrutura, as funções $f$ e $g$ denotam os morfismos entre os diferentes conjuntos de objetos, tal que $f: A \rightarrow B$ e $g: B \rightarrow C$. A função $h$, definida por $h: A \rightarrow C$ dá-se como produto da composição de $f$ e $g$. A composição de funções, conforme a seção~\ref{sec:func-para} e expressa através de $h$ na figura~\ref{fig:f-g-composition}, firma uma ligação entre o paradigma funcional e a organização estrutural derivada da CT.

A partir desta ligação, Moggi em seus trabalhos \cite{moggi1989lambdaandmonads, mogi1991notionsofcompandmonad} introduziu o conceito de monad em Haskell. Este foi capaz de fornecer os mecanismos necessários para capacitar a solução de um dos problemas fundamentais da linguagem,  pertencente ao conjunto The Awkward Squad \cite{jones2001tacklingthe}. A partir de outros conceitos como functors, categories, arrows, o trabalho de Moggi foi incrementado criando novas estruturas que estão presentes nas versões mais recentes da linguagem.

\subsection{Category -- Objetos e Morfismos}

Uma category consiste em uma coleção de coisas, todas relacionadas de algum modo. As coisas são nomeadas de objetos e as relações de morfismos \cite{spivak2014cts}.\\

\textbf{Definição}: conforme \cite{spivak2014cts, maclane1971mat}, uma category $C$ é definida como:

\begin{enumerate}[label=(\alph*), leftmargin=3em, topsep = 0pt, itemsep = 1ex, partopsep = 1ex, parsep = 1ex]
	\item uma coleção $Ob(C)$, contendo os objetos de $C$;
	\item para cada par $a, b \in Ob(C)$, um conjunto $Hom_C(a, b)$ chamado de morfismos de $a$ para $b$;
	\item para cada objeto $a \in Ob(C)$, um morfismo de \textit{identidade} em $a$ denotado por $id_a \in Hom_C(x, a)$;
	\item para cada três objetos $a, b, c \in Ob(C)$, uma função de composição $\circ: Hom_C(b, c) \times Hom_C(a, b) \rightarrow Hom_C(a, c)$;
\end{enumerate}

Dado os objetos $a, b \in Ob(C)$, denota-se o morfismo $f \in Hom_C(a, b)$ por $f: a \rightarrow b$; onde $a$ é o domínio e $b$ o contradomínio.\\

Estas operações em $C$ devem satisfazer os seguintes axiomas:

\begin{enumerate}[label={}, leftmargin = 2em, topsep = 0pt, itemsep = 1ex,partopsep = 1ex, parsep = 1ex]
	\item \textit{(Identidade)} Para todo objeto $a, b \in Ob(C)$ e todo morfismo $f: a \rightarrow b$, tem-se $id_a \circ f = f = id_b \circ f$;
	\item \textit{(Associatividade)} Sejam os objetos $a, b, c, d \in Ob(C)$ e os morfismos $f: a \rightarrow b$, $g: b \rightarrow c$ e $h: c \rightarrow d$. Então $(h \circ g) \circ f = h \circ (g \circ f)$.
\end{enumerate}

\bigskip

Ambos axiomas podem ser representados pelos diagramas comutativos das figuras~\ref{fig:comut-ident} e \ref{fig:comut-assoc}.

\begin{figure}[h]
	\begin{minipage}[t]{.48\linewidth}
		\centering
			\begin{tikzpicture}[baseline=(current bounding box.north)]
				\matrix (m) [
							matrix of math nodes,
							row sep=3em,
							column sep=5em,
							text height=2ex, text depth=0.5ex
						]{
							a & a \\
							b & b \\
						};

					\path[->]
						(m-1-1) edge node[above] {$id_a$} (m-1-2)
						(m-1-1) edge node[left] {$f$} (m-2-1)
						(m-1-2) edge node[above] {$f$} (m-2-1)
						(m-1-2) edge node[right]  {$f$} (m-2-2)
						(m-2-1) edge node[above] {$id_b$} (m-2-2);
			\end{tikzpicture}
			\caption{Identidade}
			\label{fig:comut-ident}
	\end{minipage}
	\begin{minipage}[t]{.48\linewidth}
		\centering
			\begin{tikzpicture}[baseline=(current bounding box.north)]
				\matrix (m) [
							matrix of math nodes,
							row sep=3em,
							column sep=5em,
							text height=2ex, text depth=0.5ex
						] {
							a & b \\
							c & d \\
						};
					\path[->]
						(m-1-1) edge node[above] {$f$} (m-1-2)
						(m-1-1) edge node[left] {$g \circ f$} (m-2-1)
						(m-1-2) edge node[above] {$g$} (m-2-1)
						(m-1-2) edge node[right]  {$h \circ g$} (m-2-2)
						(m-2-1) edge node[above] {$h$} (m-2-2);
			\end{tikzpicture}
			\caption{Associatividade}
			\label{fig:comut-assoc}
	\end{minipage}
\end{figure}

\subsection{Functor -- Categories e Morfismos}

Um functor $F$ consiste em um morfismo entre duas categories \cite{maclane1971mat}. Estes morfismos, chamados homomorfismos, tem como característica a preservação de estrutura de $F$. Assim como categories, functors devem satisfazer os axiomas de associatividade e identidade.\\

\textcolor{red}{<adicionar notações matemáticas e diagramas>}

\subsection{Monad -- Endofunctor e Transformações Naturais}

Endofunctors equipados com as natural transformations unit e multiplication \cite{maclane1971mat} são chamados de monad. Define-se endofunctors como functors cujos morfismos dão-se em uma mesma category. Além disso, natural transformations são morfismos entre functors, tendo como principal característica a preservação de estrutura. Como todas as estruturas já mencionadas, monads também devem satisfazer as propriedades de associatividade e identidade.\\

\textcolor{red}{<adicionar notações matemáticas e diagramas comutativos>}

\subsection{Arrow -- Kleisli Triples}

A partir de um monad podemos construir kleisli triples. Podemos pensar em kleisli triples como uma outra forma de representar sintaticamente um monad. Similar a monads, estas também obedecem as propriedades de associatividade e comutatividade.\\

\textcolor{red}{<adicionar notações matemáticas e diagramas comutativos>}

\bibliographystyle{IEEEtran}
\bibliography{references}

\end{document}
{'fraction_non_alphanumeric': 0.09023714197720974, 'fraction_numerical': 0.012900797317181672, 'mean_word_length': 4.447157502329916, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5850337', 'n_tokens_mistral': 10571, 'n_tokens_neox': 9758, 'n_words': 3478}