Skip to content

Instantly share code, notes, and snippets.

@Tchou

Tchou/find.ml Secret

Created September 26, 2024 05:58
Show Gist options
  • Select an option

  • Save Tchou/c54d6648f6d5918026b6199760ff2742 to your computer and use it in GitHub Desktop.

Select an option

Save Tchou/c54d6648f6d5918026b6199760ff2742 to your computer and use it in GitHub Desktop.
Activité 2 : fonction find et make printer
(*
Note: un prédicat sur les entiers est une fonction de type int -> bool
Écrire une fonction find qui prend en argument un prédicat, et 2 bornes
entières i ≤ j et renvoie le premier entier compris entre les bornes
qui vérifie le prédicat.
*)
let rec find pred i j =
if i > j then i (* Si l'intervale est vide:
À améliorer: voir le commentaire en fin de fichier, car
pas directement lié à la notion d'ordre supérieur *)
else if pred i then i (* sinon si le prédicat renvoie true pour i *)
else find pred (i+1) j (* sinon tester l'entier suivant *)
(* Le type de find est :
(int -> bool) -> int -> int -> int
pred i j resultat
*)
(* un prédicat simple qui teste si son argument est multiple de 10 *)
let mult10 n = n mod 10 = 0
let x = find mult10 101 115 (* x vaut bien 110 *)
(* Ici on souhaite faire une fonction (make_printer) qui
prend en argument une fonction (pred) et renvoie une nouvelle fonction.
Cette nouvelle fonction *calcule* le même résultat que pred, mais affiche
un message avant le calcul et un autre après le calcul, puis renvoie
le resultat calculé.
on utilise pour cela une fonction locale (f, ci-dessous). On montrera par
la suite une notation plus compacte.
*)
let make_printer pred =
(* make_pred prend en argument un prédicat pred (une fonction : int -> bool) *)
(* on définit une nouvelle fonction locale f qui : *)
let f n = (* prend un argument entier n *)
Printf.printf "Test sur : %d -> " n; (* affiche cet entier dans la console *)
let res = pred n in (* calcule (pred n) et stocke le résultat dans une variable locale res *)
Printf.printf "%b\n%!" res; (* affiche la valeur de res (qui est un booléen) *)
res (* renvoie res *)
in
f (* le résultat de make_printer est la fonction f, pas f appliqué quelque chose, on renvoie f
elle même *)
let mult10_pr = make_printer mult10 (* mult10_pr est une "copie" de mult10 qui fait en plus un affichage *)
let _ = mult10_pr 20 (* affiche "Test sur : 20 -> true" dans la console et renvoie true *)
let x = find mult10_pr 101 115 (* renvoie 110, mais va aussi afficher dans la console :
Test sur : 101 -> false
Test sur : 102 -> false
Test sur : 103 -> false
Test sur : 104 -> false
Test sur : 105 -> false
Test sur : 106 -> false
Test sur : 107 -> false
Test sur : 108 -> false
Test sur : 109 -> false
Test sur : 110 -> true
*)
(* Retour sur la fonction find:
Pour le cas de base i > j, on veut pouvoir signifier qu'on n'a pas trouvé de valeur vérifiant le prédicat.
On fait le choix ici de renvoyer i, qui est une valeur hors de l'intervalle (car c'est simple).
On voudrait plutôt renvoyer explicitement une erreur, par exemple lever une exception ou renvoyer une valeur
spéciale telle que None de python ou null de Java.
On revisitera cet exemple dans les prochains cours.
*)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment