Aller au menu - Aller au contenu

[CAML] ce filtrage n'est pas exhaustif

Fonction est_préséant

Pour accéder à cette section
Connectez-vous !
connexion_rpx
Page 1 
Auteur Message
1 visiteur sur ce sujet (1 Anonyme)
Page 1 
Hors ligne GautierBoëda # Posté le 08/02/2012 à 20:16:17

Bonsoir!
Pour un DM d'informatique, je dois réaliser la fonction suivante :

est_préséant : string -> string -> stringlist -> bool = <fun>

Le but de la fonction est de tester sur body_A est bien avant body_B dans la liste. D'où le bool. (Ordre de gauche à droite). Je n'ai le droit d'utiliser que les fonctions récurrentes.

J'ai d'abord réussi à créer la fonction est_préséant mais seulement si body_A et body_B se suivait... Mais j'aimerai que est_préséant vérifie cela même si body_A et body_B ne se suive pas directement.
(Fin c'est ce que j'ai compris du mot "préséant" qui est : être avant quelque chose, mais pas nécéssaire juste avant.)

Puis j'ai réussi à faire la fonction générale que voici :

Code : OCaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
let est_preseant body_A body_B (famille : string list) =
	let rec aux acc body_A body_B famille =
			match famille with
			a::[ ] -> false (* S'il ne reste plus qu'une personne, forcément B n'est pas dans la famille, donc false *)
			|t::q -> if t = body_A || acc = true
					  then if (hd(q)) = body_B
							then true
							else aux true body_A body_B q
					  else aux acc body_A body_B q
	in aux false body_A body_B famille
;;


Mon souci, et je le sais, c'est que j'ai une erreur "Exhaustif" qui se situe à la ligne "a::[ ]".
En fait, je voulais arrêter mon match juste avant la liste vide, et pas à la liste vide. Car sinon ma fonction exécutera un tour inutile et aura aussi une erreur "hd(q)" incalculable ( hd d'une liste vide est inconnu)

Je voulais savoir comment enlever l'erreur "Attention: ce filtrage n'est pas exhaustif."

Merci!


EDIT 20h24 : J'ai réussi à enlever le "exhaustif, mais je reste septique face à la longueur de ma fonction... et de la double recurrence... Y a t'il pas moyen de faire plus court? Moins couteux je veux dire?

Code : OCaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
let est_preseant body_A body_B (famille : string list) =
	let rec body fin_famille =
		match fin_famille with
		[ ] -> false
		|t::q -> if t = body_B
				  then true
				  else body q
	in
		let rec aux famille =
			match famille with
			[ ] -> false
			|t::q -> if t = body_A
					  then body q
					  else aux q
		in aux famille
;;


EDIT 21h58 : J'ai enlevé les variables Body_A/B dans les fonctions locales car inutiles.
Édité le 08/02/2012 à 21:58:57 par GautierBoëda
Publicité # Posté le 08/02/2012 à 20:16:17

Hors ligne zyd # Posté le 09/02/2012 à 00:08:27

Salut,

Tu peux faire plus court. Moins coûteux ? je ne suis pas sûr.

Tu remarqueras que tes deux fonctions aux et body sont fondamentalement la même : elles cherchent un élément dans une liste. Dans un cas (body), tu as juste besoin d’une réponse oui/non, mais dans l’autre cas (aux), en plus de cette réponse oui/non, tu as besoin de connaître la fin de la liste (après l’élément body_A).

Tu peux donc écrire une seule fonction qui cherche un élément dans une liste, et, si elle le trouve, renvoie la suite de la liste. Et tu appelles cette fonction deux fois.

La composition de ces deux appels à cette même fonction peut se faire élégamment au moyen de la fonction suivante :

Code : OCaml
1
2
3
4
let bind (x: 'a option) (f: 'a -> 'b option) : 'b option =
  match x with
  | Some a -> f a
  | None -> None


Bonne prog,
--
Zyd.
Hors ligne PotageFumants # Posté le 11/02/2012 à 02:31:22
Avatar
Groupe : Bannis

Code : OCaml
1
2
3
4
5
6
7
let est_preseant a b =
  let rec aux y = function
    | [] -> false
    | x :: xs ->
      if x = b then y
      else aux (x = a || y) xs
  in aux false

Pourquoi chercher les choses compliquées ?
Édité le 11/02/2012 à 02:31:47 par PotageFumants

Retour au forum "Autres langages, outils et approches" ou à la liste des forums

Pour accéder à cette section
Connectez-vous !
connexion_rpx