Discussion:
faire des modules
(trop ancien pour répondre)
Mihamina Rakotomandimby (R12y)
2009-01-08 07:18:30 UTC
Permalink
Bonjour,
Je reviens vers OCaml apres plusieurs mois de PHP forcé, j'essaie de
retrouver mes marques.

La doc que je lis:
http://caml.inria.fr/pub/docs/manual-ocaml/manual004.html#toc17
Mon anglais n'est pas encore assez bon pour que je sois certain de tout
comprendre.

Si je veux faire mon propre module, est ce que je dois ecrire moi meme
le contenu entre "struct"/"end" et entre "sig"/"end" et les mettre dans
deux fichiers séparés dont les extension sont respectivement "ml" et "mli"?
Ou bien y a t il une option (pas décrite dans cette doc) à transmettre à
"ocamlc" pour qu'il génère automatiquement les "cmo" et "cmi" qui vont
bien à partir d'un "ml"?

Avant de vraiment poster ce message, je me mets à relire encore la page
sus-indiquée, et je vois ceci:

module A: sig (* contents of file A.mli *) end
= struct (* contents of file A.ml *) end;;

Ca m'emmène à la réponse à ma question: Il faut que je remplisse moi
meme le "mli".

Supposons que je souhaite "publier" toutes les fonctions d'un module, la
manière simple et sure d'avoir la signature est encore de copier coller
dans l'interpreteur interactif le module que j'aurais écris et de
récupérer la sortie, non? C'est cette sortie que je colle dans le "mli".

Je me trompe totalement, ou bien ça semble aller dans le bon sens?
Merci d'avance.
Joe Cool
2009-01-08 08:12:38 UTC
Permalink
La manière la plus simple d'implémenter un module est d'écrire un
fichier ml contenant la définition de toutes les valeurs du module:

=== Toto.ml ===
let id x = x
================

Ensuite, quand on le compile avec la commande:

$ ocamlc -c Toto.ml

on obtient un fichier d'interface compilé Toto.cmi et un fichier objet
Toto.cmo, tout deux implémentant un module appelé Toto. Le compilateur
retrouve l'interface en cherchant dans son path (la liste des
répertoires passés en paramètres avec l'option -I).

On peut aussi écrire un fichier d'interface à part pour contraindre la
signature du module:

=== Toto.mli ===
val id : int -> int
================

puis compiler les fichiers comme suit:

$ ocamlc -intf Toto.mli
$ ocamlc -c -impl Toto.ml


l'option -impl demande au compilateur de ne pas générer de fichier cmi.

Avec la commande:

$ ocamlc -i Toto.ml

le compilateur affiche à l'écran la signature la plus générale du module
Toto, ce qui permet d'obtenir un fichier mli à peu de frais:

$ ocamlc -i Toto.ml > Toto.mli

Les définitions de module avec les constructions sig...end et
struct...end sont plus compliquées (sans parler des foncteurs...);
heureusement, elles ne sont pas nécessaires pour coder des modules
simples «à la C».
--
Joe Cool
Lucky-84
2009-01-11 10:35:49 UTC
Permalink
Bonjour,

Comme l'a dit Joe Cool, il est très simple d'implémenter tes fonctions
dans un fichier .ml sans utiliser de struct/end, et d'implémenter
l'interface dans un fichier .mli sans utiliser de sig/end .

Pour compiler, il y a une manière très simple de procéder :

$ocamlc -o tonExecutable interfaceModule.mli module.mli

Si tu as plein de modules et d'interfaces, tu peux faire (tout
simplement :)

$ocamlc -o executable interface1.mli interface2.mli interface3.mli
module1.ml module2.ml module3.ml

et ainsi de suite.

Par contre, il faut faire attention: l'interface doit être compilée
avant le module.

Cordialement,
Lucky-84

PS: si tu veux, il existe un livre ultra-complet en ligne, gratuit, en
français à ce lien :
http://www.pps.jussieu.fr/Livres/ora/DA-OCAML/index.html
Planar
2009-01-13 10:54:50 UTC
Permalink
Post by Joe Cool
$ ocamlc -intf Toto.mli
Inutile de mettre "-intf". Cette option signifie: "traite ce fichier comme si
son nom se finissait par .mli".
Post by Joe Cool
$ ocamlc -c -impl Toto.ml
De meme, l'option "-impl" n'est pas necessaire.
Post by Joe Cool
l'option -impl demande au compilateur de ne pas générer de fichier cmi.
Erreur. Le compilateur genere un fichier.cmi s'il n'y a pas de .mli correspondant
au .ml. L'otion -impl n'a aucune influence sur cette decision.


A part ca, tes conseils sont bons.
--
Planar
remove .invalid from my address to send me mail

"Surprise. Then just use AGA rules and that's it." - Robert Jasiek
Joe Cool
2009-01-16 18:17:37 UTC
Permalink
Post by Planar
Inutile de mettre "-intf". Cette option signifie: "traite ce fichier comme si
son nom se finissait par .mli".
[...]
Post by Planar
Erreur. Le compilateur genere un fichier.cmi s'il n'y a pas de .mli correspondant
au .ml. L'otion -impl n'a aucune influence sur cette decision.
Comme quoi il vaut mieux se fatiguer à lire la doc en plus de tester sur
des exemples.
Post by Planar
A part ca, tes conseils sont bons.
C'est toujours ça de gagné. Mais comme l'option -impl génère le fichier
cmi quand il est manquant, y a-t-il une méthode de compilation canonique
pour associer plusieurs interfaces à une même implémentation? Je pensais
que c'était possible avec -intf et -impl, mais il semblerait qu'il n'y
en ait pas.

Par exemple, on dispose de l'implémentation suivante:

=== IdGen.ml ===
let id x = x
================

mais on veut y accéder via deux interfaces différentes:

=== IdInt.mli ===
val id : int -> int
=================

et

=== IdBool.mli ===
val id : bool -> bool
==================

en imaginant qu'on prototype une application avec un module générique
que l'on souhaitera optimiser pour chaque type, le tout sans avoir à
dupliquer artificiellement l'implémentation générique (et sans foncteur).
--
Joe Cool
Planar
2009-01-25 21:06:17 UTC
Permalink
Post by Joe Cool
C'est toujours ça de gagné. Mais comme l'option -impl génère le fichier
cmi quand il est manquant, y a-t-il une méthode de compilation canonique
pour associer plusieurs interfaces à une même implémentation? Je pensais
que c'était possible avec -intf et -impl, mais il semblerait qu'il n'y
en ait pas.
Que je sache, il n'y en a pas. Quand on a besoin de faire ce genre de manip, il faut
utiliser des foncteurs.
--
Planar
remove .invalid from my address to send me mail

"Surprise. Then just use AGA rules and that's it." - Robert Jasiek
Loading...