Programmation Fonctionnelle, TD5

Version & licenses
Creative Commons License

Programmation Fonctionnelle, TD5 : types algébriques.

Guyslain Naves

Exercice 1 : Nombres binaires sans chiffre '0'

Nous allons coder les entiers sans le chiffre '0', mais seulement avec les chiffres '1' et '2'. Ainsi, on peut montrer que tout nombre naturel $n$ se décompose en $n = \sum_{i=0}^k \alpha_i 2^i$, pour un certain choix de $\alpha_i \in \{1,2\}$.

Par exemple, $0 = \sum_{i=0}^{-1} 1 \cdot 2^{i}$, et $8 = 2 \cdot 2^0 + 1 \cdot 2^1 + 1 \cdot 2^2$, etc. Étant donné que les bits ont toujours pour valeurs des puissances de 2, on peut considérer, selon la valeur du dernier bit, qu'un entier vaut soit $1$ plus le double d'un entier, soit $2$ plus le double d'un entier, soit $0$.

  1. Proposer un type algébrique inductif pour les entiers naturels, ainsi codés. (utiliser un cas spécial pour coder l'entier $0$).
  2. Écrire une fonction succ, qui à $n$ associe $n+1$.
  3. Coder l'addition de deux entiers sous cette représentation.

Exercice 2 : Les arbres enracinés

Nous souhaitons travailler avec des arbres d'arités arbitraires, dont les feuilles sont des entiers. Les nœuds internes ne possèdent pas d'information, sinon la liste de leurs fils.

  1. Proposer un type pour encoder les arbres enracinés.
  2. Écrire une fonction prenant deux arbres enracinés, qui les lie avec une nouvelle racine ayant pour fils ces deux arbres.
  3. Écrire une fonction prenant une liste d'entiers, et qui construit un arbre enraciné dont les feuilles sont les éléments de la liste. L'arbre ainsi construit doit avoir une hauteur de $1$.
  4. Écrire une fonction qui calcule la somme des feuilles d'un arbre enraciné.
  5. Écrire une fonction qui calcule le maximum des valeurs des feuilles d'un arbre enraciné.
  6. Pouvez-vous généraliser les deux fonctions précédentes ?
  7. Écrire une fonction map, qui applique une fonction passée en argument à chaque feuille, et renvoie l'arbre enraciné de même forme avec les images de la fonction en feuilles.
  8. Écrire une fonction prenant en argument un entier $n$, et qui calcule un arbre binaire complet de hauteur $n$ dont les feuilles sont les entiers de $1$ à $2^n$.
  9. Regrouper le type des arbres enracinés et ses fonctions dans un module.

Exercice 3 : Le type option

Le module Pervasive fournit un type bien utile, le type option permettant de coder une valeur optionnelle :

  1. type 'a option =
  2. | None
  3. | Some of 'a
  1. coder une fonction qui filtre les options d'une liste, pour garder uniquement les valeurs définies :

    1. val option_filter : 'a option list -> 'a list
  2. quel est le type de la fonction suivante ?

    1. let (>>=) e f = match e with
    2. | None -> None
    3. | Some v -> f v
  3. Utiliser >>= pour coder une fonction prenant trois arguments de type int option, et qui renvoie une option contenant la somme des trois entiers, s'ils sont définis, ou None sinon.
  4. Écrire une fonction map : ('elt -> 'im) -> 'elt option -> 'im option. Proposer une version utiliser un filtrage par motif, et une version utilisant uniquement (>>=).
  5. Coder une fonction find : ('elt -> bool) -> 'elt list -> 'elt option, qui calcule le premier élément d'une liste vérifiant un prédicat. find calcule une option car il se peut qu'aucun élément de la liste ne vérifie le prédicat.