|
Postscript, PDF | Didier Rémy | Polytechnique, INRIA |
|
|
||||
|
|
· | Un petit langage fonctionnel typé. |
· | Manipule des collections de définitions (de valeurs, de types) du langage de base. |
· | Leurs types: des collections de déclarations/spécifications (types des valeurs, déclarations des types). |
· | Modules emboîtés. |
· | Fonctions (foncteurs) et application de fonctions. |
|
struct
p1 ...pn end
définitions de valeurs et de fonctions | let x = ... |
définitions de types | type t = ... |
définitions d'exceptions | exception E [of ...] |
définitions de classes | class C = ... end |
Plus: | |
définition de sous-modules | module X = ... |
définition de type de module | module type S = ... |
module
.
|
|
... (Z.f Z.x : Z.t) ... |
open
module permet d'omettre
le préfixe et le point:
open Z ... (f x : t) ... |
|
|
|
NB: La notation open T.R rend les composantes de T.R
visibles dans la suite du corps de Q mais n'ajoute pas ces composantes à
Q . |
|
sig s1 s2 ... end |
|
spécification de valeurs | val x : s |
spécification de types abstraits | type t |
spécification de types manifestes | type t = t |
spécification d'exceptions | exception E |
spécification de sous-modules | module X : M |
spécification de type de module | module type S [ = M] |
module type
module type MA_SIGNATURE = sig ... end |
|
Structures (implémentations) | Signatures (interfaces) | |
Séquence de définitions | Séquence de spécifications de types | |
Valeurs | ||
let x = [1] | val x : int list | |
let rec f x = ... | val f : int -> int | |
Exceptions | ||
exception E of string | exception E of string | |
Types concrets | ||
type t = int | type t = int | |
type 'a u = A | B of 'a | type 'a u = A | B of 'a | |
Types abstraits | ||
type v = string | type v |
|
Module
|
Signature inférée
|
|
· | vérifie que la structure satisfait la signature (toutes les composantes spécifiées dans la signature doivent être définies dans la structure, avec des types au moins aussi généraux); |
· | rend inaccessibles les parties de la structure qui ne sont pas spécifiées dans la signature; |
· | produit un résultat qui peut être lié par module M = ... |
module X : S = M
module X = (M : S)
|
|
|
M.x;; (* Unbound value M.x *) M.f 1 + 1;; (* S.f 1 of type M.t is used with type int *) |
|
|
|
|
Float
le type t
est concret donc il peut être confondu avec
"float". Par contre, il est abstrait dans les modules Euro
et
Dollar
ci-dessous:
|
Euro.t
et Dollar.t
sont isomorphes mais
incompatibles.
|
Euro
et Dollar
.
|
Euro
et
Dollar
. Quel est le problème? Avez-vous une idée de la solution?
Donner la signature BUREAU_DE_CHANGE
des valeurs exportées
par le module Bureau_de_change
.
Donner l'implémentation du module Bureau_de_change
.
Tester votre implémentation.
|
|
|
Plus.t
est incompatible avec Euro.t
.t
est partiellement abstrait et compatible avec
"Euro.t", et la vue Plus
permet de manipuler les valeurs construites
avec la vue Euro
.
|
PLUS with type t = Euro.t
est une abréviation
pour la signature
sig type t = Euro.t val plus: t -> t -> t end |
|
|
· | Le fichier d'implémentation a.ml :une suite de phrases semblable à l'intérieur de struct ... end
|
· | Le fichier d'interface a.mli (optionnel):une suite de spécifications semblable à l'intérieur de sig ... end
|
B
peut faire référence à A
comme si
c'était une structure, en utilisant la notation pointée
A.x
ou bien en faisant open A
.
|
ocamlc -c a.mli | compile l'interface de A |
crée a.cmi |
|
ocamlc -c a.ml | compile l'implémentation de A |
crée
a.cmo |
|
ocamlc -c b.ml | compile l'implémentation de B |
crée
b.cmo |
|
ocamlc -o monprog a.cmo b.cmo édition de liens finale |
module A sig (* contenu de a.mli *) end = struct (* contenu de a.ml *) end module B = struct (* contenu de b.ml *) end |
|
|
functor
(Z : T) ->
M
|
|
|
|
|
module type BANQUE = (* vue du banquier *) sig type t type monnaie val créer : unit -> t val dépôt : t -> monnaie -> monnaie val retrait : t -> monnaie -> monnaie end module type CLIENT = (* vue donnée au client *) sig type t type monnaie val dépôt : t -> monnaie -> monnaie val retrait : t -> monnaie -> monnaie end;; |
|
module Banque_au_porteur (M : MONNAIE) : BANQUE with type monnaie = M.t = struct type monnaie = M.t and t = { mutable solde : monnaie } let zéro = M.prod 0.0 M.un and neg = M.prod (-1.0) let créer() = { solde = zéro } let dépôt c x = if x > zéro then c.solde <- M.plus c.solde x; c.solde let retrait c x = if c.solde > x then (c.solde <- M.plus c.solde (neg x); x) else zéro end;; module Poste = Banque_au_porteur (Euro);; |
|
module Client : CLIENT with type monnaie = Poste.monnaie with type t = Poste.t = Poste;; let mon_ccp = Poste.créer ();; Poste.dépôt mon_ccp (euro 100.0);; Client.dépôt mon_ccp (euro 100.0);; |
module Citybank = Banque_au_porteur (Dollar);; let mon_compte_aux_US = Citybank.créer();; |
Citybank.dépôt mon_ccp;; Citybank.dépôt mon_compte_aux_US (euro 100.0);; |
|
module Banque_centrale = Banque_au_porteur (Euro);; module Poste = Banque_au_porteur (Euro);; |
module Banque (M : MONNAIE) : BANQUE with type monnaie = M.t = struct let zéro = M.prod 0.0 M.un and neg = M.prod (-1.0) type t = int type monnaie = M.t type compte = { numéro : int; mutable solde : monnaie } let comptes = Hashtbl.create 10 and last = ref 0 let compte n = Hashtbl.find comptes n let créer() = let n = incr last; !last in Hashtbl.add comptes n {numéro = n; solde = zéro}; n let dépôt n x = let c = compte n in if x > zéro then c.solde <- M.plus c.solde x; c.solde let retrait n x = let c = compte n in if c.solde > x then (c.solde <- M.plus c.solde x; x) else zéro end;; |
|
Banque_au_porteur
et "Banque" implémentent la même interface
et sont interchangeables
module Poste = Banque_au_porteur(Euro);; module La_Poste = Banque(Euro);; module Citybank = Banque(Dollar);; |
|
|
'a pile
des piles d'élément de type 'a
,
modifiables en place . Définir une fonction de
créer: unit -> 'a pile
qui retourne une pile vide.
Écrire les fonctions ajouter : 'a -> 'a pile -> unit
et
retirer : 'a pile -> 'a
d'ajout en pile et de retrait du dernier
élément. On lancera une exception lorsque l'on essaye de retirer un élément
d'une pile vide.
En faire un module Pile
permettant de rendre la représentation des
piles abstraite.
Utiliser la commande make pour
compiler le programme.cpile
,
avec une fonction consulter
qui retourne le sommet de la pile sans le
retirer, mais on ne dispose que du code compiler et de son interface.
Que manque-t-il pour fournir une implémentation plus efficace de la méthode
sommet? piles.ml
sans se soucier de la compilation séparée.
|
· | Réaliser une bibliothèque fournissant les opérations sur les polynômes à une variable. Les coefficients forment un anneau passé en argument à la bibliothèque. |
· | Vérifier l'égalité (X + Y) (X -Y) = (X2 - Y2) en considérant les polynômes à deux variables comme polynôme en X à coefficients les polynôme en Y. |
· | Vérifiez les mêmes égalités dans l'anneau Z/2Z. Z/2Z. |
· | Écrire un programme qui prend un polynôme sur la ligne de commande et
l'évalue en chacun des points lus dans stdin (un entier par
ligne). Le résultat est imprimé dans stdout .
|
· | Utiliser la commande make pour compiler le programme. |
· | Écrire une autre implémentation des polynômes, par exemple par des polynomes creux. |
· | Écrire une version spécialisée des polynômes dans Z/2Z utilisation une représentation pleine et des opérations logiques sur des vecteurs de bits (on pourra se limiter à des polynômes de faible degré à condition de tester le débordemnent). |
This document was translated from LATEX by HEVEA and HACHA.