\input{../.headers/cours.tex}
\renewcommand{\texttt}[1]{\mintinline{ocaml}{#1}}

\baselineskip15pt

\begin{center}
\shadowbox{\LARGE \bf \textsc{\supline Cr\'eation de types en Caml\subline}}\\
\textsc{{\large Cours -- TP}}\subline\\
\end{center}

\section{Types alias.}

\medskip

\subsection{Exemples}

C'est un type existant mais auquel on attribue un nouveau nom avec la syntaxe \texttt{type ... = ...}

\exx ~~
On peut d\'efinir le type \texttt{mot} des listes de caract\`eres~:
\begin{minted}{ocaml}
type mot = char list;;
\end{minted}
\xxe

On peut imposer le type d'une fonction d\'efinie sur ou \`a valeurs dans un type alias.\\
Un exemple avec la fonction qui calcule le miroir d'un mot~:
\begin{minted}{ocaml}
let miroir (m : mot) : mot = List.rev m;;
\end{minted}

Un type peut \^etre polymorphe, \cad \^etre param\'etr\'e par un ou plusieurs autres types.

\exx ~~
On peut d\'efinir le type \texttt{'a biglist} des listes de listes d'\'el\'ements de type 'a~:
\begin{minted}{ocaml}
type 'a biglist = 'a list list;;
\end{minted}
\xxe


\medskip

\subsection{Travaux pratiques}

\medskip

\exo \'Ecrire les fonctions \texttt{string_of_mot : mot }$\rightarrow$\texttt{ string} et \texttt{mot_of_string : string }$\rightarrow$\texttt{ mot} r\'ealisant les conversions d'un mot en chaine de caract\`ere et inversement, en forcant leur types.

\inputminted{ocaml}{./cours_exo_1.ml}


\section{Types somme}

\medskip

\subsection{Exemples}

\medskip

Le mot "somme" dans ce contexte d\'esigne une r\'eunion disjointe, et se note $|$. Chaque terme de la r\'eunion disjointe est introduit par un \textit{constructeur} (qui peut avoir $0$, $1$ ou plusieurs arguments) dont le nom commence par une majuscule. Le \textit{pattern-matching} s'applique pr\'ecis\'ement aux types somme (on filtre suivant le constructeur utilis\'e pour d\'efinir l'\'el\'ement ayant le type somme).

\exx~~
Le type \texttt{couleur} suivant a trois constructeurs qui n'ont aucun argument.
\begin{minted}{ocaml}
type couleur = Bleu | Rouge | Vert;;
\end{minted}
\xxe

\exx~~
Le type \texttt{nombre} suivant a deux constructeurs qui ont chacun un argument.
\begin{minted}{ocaml}
type nombre = Entier of int | Flottant of float;;
\end{minted}
\xxe


\medskip

\subsection{Travaux pratiques}

\medskip

\exo \'Ecrire une fonction \texttt{somme : nombre }$\rightarrow$\texttt{ nombre}$\rightarrow$\texttt{ nombre} 
pertinente
%qui calcule la somme de deux \'el\'ements de type \texttt{nombre}

\inputminted{ocaml}{./cours_exo_2.ml}

\section{Types produits et enregistrements}

\medskip

\subsection{Exemples}

\medskip


\textbf{\textsc{Types produits}}~:\\
Si \texttt{'a} et \texttt{'b} sont deux types alors \texttt{'a*'b} est le type des couples \texttt{(x,y)} avec \texttt{x} de type \texttt{'a} et \texttt{y} de type \texttt{'b}.

\rmq ~On peut d\'efinir de m\^eme de types produits avec $n\geq 3$ facteurs plut\^ot que $2$.
\qmr

\exx ~~On peut d\'efinir le type \texttt{complexe} comme un alias du type \texttt{float * float}\\

\xxe

\smallskip

\textbf{\textsc{Types enregistements}}~:\\
C'est le m\^eme principe mais en permettant de \textit{nommer} les diff\'erents \'el\'ements du couple (ou du n-uplet). Ainsi pour les complexes, il est plus ag\'eable de pouvoir clairement sp\'ecifier ce qu'est la partie r\'eelle et ce qu'est la partie imaginaire.

\exx 
\begin{minted}{ocaml}
type complexe = {re : float ; im : float};;
\end{minted}
\xxe


\medskip

\subsection{Travaux pratiques}

\medskip

\exo D\'efinir le nombre complexe $\mathbf{i}$, et les fonctions somme et produit sur les complexes.

\inputminted{ocaml}{./cours_exo_3.ml}

\medskip

\subsection{Mutabilit\'e}

\medskip

Par d\'efaut, un type enregistement est un type \textit{immuable}. On ne peut pas modifier les champs des enregistements d'un m\^eme \'el\'ement apr\`es l'avoir d\'efini, on peut seulement cr\'eer un nouvel \'el\'ement avec des champs diff\'erents (de ce point de vue, les types enregistrements se comportent comme les listes et pas comme les tableaux). \\[0.2cm]
{\bf Il est n\'eanmoins possible d'y rem\'edier en sp\'ecifiant que les champs concern\'es peuvent \^etre mutables.}

\exx
\begin{minted}{ocaml}
type cplx = {mutable re : float ; mutable im : float};;

let z = {re = 2.0; im = 5.0}
z.re <- 3.0
\end{minted}
\xxe

\bigskip

\section{Types inductifs}

Dans le contexte des types, le mot inductif signifie r\'ecursif.

\medskip
\subsection{L'exemple-type}
\medskip

On conna\^it d\'ej\`a un type inductif~: le type (polymorphe) \texttt{'a list}. Red\'efinissons-le~!\megasubline

\exx ~~Le type \texttt{'a liste}~:
\begin{minted}{ocaml}
type 'a liste = Vide | Cons of 'a*('a liste);;
\end{minted}
\xxe

\medskip

\subsection{Travaux pratiques}

\medskip

\exo \'Ecrire une fonction qui convertit une \texttt{'a liste} en {'a list}.

\inputminted{ocaml}{./cours_exo_4.ml}

\exo Proposer d'autres types inductifs.

\inputminted{ocaml}{./cours_exo_5.ml}

\end{document}
