2010-08-08 4 views
7

Il y a cette fonction d'index dans « Erlang Programmation »:Pourquoi "quand" est-il utilisé dans cette fonction?

index(0, [X|_]) -> X; 
index(N, [_|Xs]) when N>0 -> index(N-1, Xs) 

est-ce pas la garde « lorsque N> 0 » superflu en raison de la correspondance de motif? L'indice d'appel (0, Liste) ne finira jamais dans la deuxième clause, donc N sera toujours> 0. Ou ai-je totalement tort ici?

+0

ne sait pas Erlang (seulement OCaml) donc je vais laisser comme un commentaire: Quel modèle correspondrait N == - 1 Ma conjecture serait la seconde (si ce n'était pas pour la garde) –

+0

Rune FS , Cela a été ma première pensée aussi, mais l'index (-1, [1,2,3]) aboutit à "** erreur d'exception: pas de test de correspondance de clause de fonction: index (-1, [1,2,3])" –

+0

mais si vous supprimez le garde ne correspond pas alors? –

Répondre

12

La fonction fonctionne correctement pour N> = 0. Sans un garde, pour N < 0 il traverserait la liste entière:

index (-2, [1,2,3]) -> index (-3, [2,3]) -> ... -> index (-5, []) -> erreur.

Ce n'est pas un gros problème, seulement vous pourriez avoir une exception déroutante. Dans les langages avec des listes infinies (Haskell, Ocaml), l'oubli de cette garde pourrait conduire à une boucle infinie: index (-1, [0,0,0 ..]).

6

La clause when protège contre les index négatifs (modifier: voir les commentaires à la question d'origine;).

5

Il donne également un code plus clair lorsque vous dites explicitement que cette clause est valide, pas seulement par défaut. Oui, je sais que dans certains (nombreux) cas, il n'est pas possible de faire correctement car le test peut devenir très complexe ou que vous voulez une forme de cas par défaut. Mais pas ici.

Questions connexes