• Aucun résultat trouvé

D´efinitions de type

N/A
N/A
Protected

Academic year: 2022

Partager "D´efinitions de type"

Copied!
8
0
0

Texte intégral

(1)

D´efinitions de type

Les types ´enum´er´es

La d´efinition d’un type se fait `a l’aide du mot cl´e type. Les noms des constructeurs commencent par une majuscule. Un construc- teur permet de construire les valeurs d’un type et d’acc´eder aux composantes de ces valeurs grˆace au filtrage des motifs.

# type couleur = Bleu | Rouge | Vert;;

type couleur = Bleu | Rouge | Vert

# Vert;;

- : couleur = Vert

# let valeur = function Bleu -> 1

| Vert -> 2

| Rouge -> 3;;

val valeur : couleur -> int = <fun>

# valeur Vert;;

- : int = 2

La somme de deux types

La somme de deux types correspond `a l’union disjointe.

# type int_ou_bool = I of int | B of bool;;

type int_ou_bool = I of int | B of bool

# I;;

The constructor I expects 1 argument(s), but is here applied to 0 argument(s)

(2)

# I 4;;

- : int_ou_bool = I 4

# B true;;

- : int_ou_bool = B true

# B 5;;

This expression has type int but is here used with type bool

L’utilisation des expression de ce type se fait par “pattern match- ing”.

# let f = function

B x -> if x then 1 else 2

| I x -> x+4;;

val f : int_ou_bool -> int = <fun>

# let f’ = function B true -> 1

| B false -> 2

| I x -> x+4;;

val f’ : int_ou_bool -> int = <fun>

# type string_ou_intlist =

S of string | IL of int list;;

type string_ou_intlist = S of string | IL of int list

# type (’a,’b) somme = G of ’a | D of ’b;;

type (’a, ’b) somme = G of ’a | D of ’b

# G 1;;

- : (int, ’a) somme = G 1

# G true;;

- : (bool, ’a) somme = G true

# D [1; 2];;

- : (’a, int list) somme = D [1; 2]

(3)

Les listes

Des valeurs d’un mˆeme type peuvent ˆetre regroup´ees en des listes.

Le type list est en fait un sch´ema de type pr´ed´efini. La plu- part des fonctions de manipulation des listes sont d´efinies dans la biblioth`eque List.

La liste vide est une valeur non fonctionnelle qui est de type poly- morphe. Objective Caml permet de g´en´erer des listes d’objets de mˆeme type sans que ce type soit pr´ecis´e. Ce polymorphisme est appel´e param´etrique.

# [];;

- : ’a list = []

# 1::[];;

- : int list = [1]

# [1;2] @ [3;4;5];;

- : int list = [1; 2; 3; 4; 5]

On note [e1;...;en] la liste e1::(e2::... (en::[])...).

# [[1;2];[];[6];[7;8;5;2]];;

- : int list list = [[1; 2]; []; [6]; [7; 8; 5; 2]]

La “d´estructuration” des listes (extraction des ´el´ements) se fait par

“pattern-matching”.

# let f = function [] -> 0

| x::l -> x+1;;

val f : int list -> int = <fun>

# f [];;

(4)

- : int = 0

# f [3;2;7];;

- : int = 4

# let f = function [] -> 0

| []::l -> 1

| (x::l)::m -> x+1;;

val f : int list list -> int = <fun>

# f [ []; [1;2] ];;

- : int = 1

# f [ [3;2]; []; [1;4] ];;

- : int = 4

Fonctions r´ecursives sur les listes

Dans l’exemple suivant on calcule la somme des ´el´ements d’une liste d’entiers.

# let rec somme = function [] -> 0

| x::l -> x+somme l;;

val somme : int list -> int = <fun>

# somme [3;2;7];;

- : int = 12

Dans l’exemple suivant on calcule la conjonction des ´el´ements d’une liste de bool´eens.

# let rec conj = function [] -> true

| x::l -> x & conj l;;

val conj : bool list -> bool = <fun>

# conj [true; false; true];;

- : bool = false

(5)

# let rec longueur = function [] -> 0

| x::l -> 1 + longueur l;;

val longueur : ’a list -> int = <fun>

# longueur [true; false];;

- : int = 2

# longueur [[1];

On peut ´egalement utiliser la fonction tl (tail) de la librairie List

# let rec longueur l = if l=[] then 0

else 1 + longueur (List.tl l)

;;

val longueur : ’a list -> int = <fun>

On peut enfin utiliser la fonction length de la biblioth`eque List.

Attention elle prend un temps proportionnel `a la longueur de la liste.

# List.length [1;3;5];;

- : int = 3

# List.hd [1;3;5];;

- : int = 1

(6)

La fonctionnelle map

Consid´erons l’exemple suivant.

# let rec succl=function [] -> []

| x::l -> (x+1)::succl l;;

val succl : int list -> int list = <fun>

# succl [2;1;5];;

- : int list = [3; 2; 6]

Voici maintenant une fonction qui `a une liste d’entiers [n1;. . . , nk] associe la liste de bool´eens [b1;. . .;bk] telle que bi soit true si et seulement si ni est pair.

let rec pairl = function [] -> []

| x::l -> ((x mod 2)=0)::pairl l;;

val pairl : int list -> bool list = <fun>

# pairl [1;4;6;3;8];;

- : bool list = [false; true; true; false; true]

La fonctionnelle map est d´efinie dans la librairie List. Son type est

# List.map;;

- : f:(’a -> ’b) -> ’a list -> ’b list = <fun>

et son effet est le suivant.

List.map f[e1;. . .;en] = [fe1;. . .;fen] Cette fonction peut aussi s’´ecrire de la fa¸con suivante.

# let rec map f = function [] -> []

| x::l -> (f x)::map f l

(7)

;;

val map : (’a -> ’b) -> ’a list -> ’b list = <fun>

On peut alors r´e´ecrire les expressions vues plus haut en

# List.map (function x->x+1) [3; 2; 6];;

- : int list = [4; 3; 7]

# List.map (function x->(x mod 2)=0) [1;4;6;3;8];;

- : bool list = [false; true; true; false; true]

Exercice Synth´etiser le type de map.

Fonctionnelles d’it´erations sur les listes

Il y a en Objective Caml deux fonctionnelles d’it´erationfold left et fold right d´efinies dans la librairie List. Ces deux fonction- nelles permettent l’´ecriture compacte d’une fonction de calcul sur les ´el´ements d’une liste comme la somme des ´el´ements.

Leurs effets sont les suivants.

fold right f [e1;e2;. . .;en] a = (fe1(fe2 . . .(fena))

fold left f a [e1;e2;. . .;en] = (f . . . (f(fa e1)e2) . . . en)

# let rec somme = function [] -> 0

| x::l -> x + somme l;;

val somme : int list -> int = <fun>

La fonction somme peut s’´ecrire

# let add x y = x+y;;

val add : int -> int -> int = <fun>

# let somme l = List.fold_right add l 0;;

val somme : int list -> int = <fun>

# somme [3;1;9];;

- : int = 13

(8)

# List.fold_right;;

- : f:(’a ->’b ->’b) ->’a list->init:’b ->’b = <fun>

# List.fold_left;;

- : f:(’a ->’b ->’a) ->init:’a ->’b list ->’a = <fun>

L’´ecriture directe defold rightpeut se faire de la fa¸con suivante.

# let rec fold_right f l a = match l with

[] -> a

| x::reste -> f x (fold_right f reste a);;

val fold_right:(’a ->’b ->’b)->’a list ->’b ->’b =<fun>

On peut ´egalement red´efinir la fonction map.

# let map f l =

List.fold_right (fun x m -> (f x)::m) l [];;

val map : (’a -> ’b) -> ’a list -> ’b list = <fun>

De mˆeme, la fonction qui concat`ene deux listes peut s’´ecrire :

# let append l m =

List.fold_right (fun x n -> x::n) l m;;

val append : ’a list -> ’a list -> ’a list = <fun>

# append [1;2;3] [4;5;6;7];;

- : int list = [1; 2; 3; 4; 5; 6; 7]

Elle est pr´ed´efinie dans la biblioth`eque List.

# List.append [1;2;3] [4;5;6;7];;

- : int list = [1; 2; 3; 4; 5; 6; 7]

Références

Documents relatifs

L’op´eration r´eciproque, de passage d’un arbre binaire de recherche `a un arbre balis´e, peut se faire en ajoutant d’abord des feuilles pour compl´eter l’arbre (au sens

Quels sont les ´ el´ ements nilpotents d’un anneau int`

Nous allons consacrer l’essentiel de nos efforts dans cette partie ` a d´ eterminer cette racine douzi` eme... cubiques) primitives de l’unit´ e de Z/pZ.. Cette involution laisse

Dans la logique du second ordre, on utilise un deuxi`eme type de variables, appel´ees variables du second ordre, qui repr´esentent des relations.. LIAFA, CNRS et Universit´ e

El´ ements d’algorithmique. EA4 (3

Ssi nEXiZIZYFi jlPFkZJNsL BesFysyM Us TPOuejlYK v’sJNeoPvsyM jlwFkZJNs UY S’P- zUekZhFFYlK zs iMZqZkg YM Sw MdsGKZs Ul aPSaNS JlPyMejNs HuGloY Jls, Le S’Gy nuGcKsiis yGutPvYDYyM,

Ecrire une classe ´ Complex pour la manipulation des nombres complexes compor- tant comme attributs deux coordonn´ees r´eelles (la partie r´eelle et la partie imagi- naire) et

La construction support g´ en` ere toutes les parties mais quand mˆ eme on a d’autres constructions de parties :. le compl´ ementaire l’intersection la r´