2017-10-18 7 views
2

Je travaille sur une fonction simple qui devrait, donné x, retourner un tuple (y, z) tel que y <= abs(5) + z * 10 = x, où z la plus petite valeur possible. En C, je bouclerais z++ et y++, jusqu'à ce que leur somme corresponde à x.Incrément fonctionnel

Actuellement, j'essaie de résoudre ce problème fonctionnellement. S'il vous plaît considérer l'exemple suivant:

let foo x = 
    let rec aux (y, z, q) = 
     match (y + z * 10) with 
     q  -> (y, z) 
     |_  -> aux(y + 1, z + 1, q) //How to correctly set the increments? 
    aux(0, 0, x) 

Cette approche renvoie toujours (0, 0), peu importe quoi. Je me suis référé à this question, tout en pensant à une solution. Je suis conscient que les variables mutables devraient être évitées, et c'est ce que je fais. Malheureusement, je crains d'avoir manqué le point, quelque part, donc j'aborde le problème du mauvais côté.

Répondre

4

Vous introduisez une nouvelle liaison q pour le résultat de l'expression évaluée dans votre première correspondance de cas plutôt que de la comparer. Ce que vous voulez est quelque chose comme ceci:

match (y + z * 10) with 
| r when r = q -> (y, z) 
| _ -> aux(y + 1, z + 1, q) 
+0

J'ai compris, merci. – Worice

1

Dans F # vous êtes généralement soit dans une expression de valeur ou une expression de correspondance de modèle. Lorsque vous faites ceci:

match (y + z * 10) with 
q  -> (y, z) 

Vous êtes effectivement en disant: « Calculer y + z * 10 et toujours affecter le résultat à une nouvelle variable q, ignorez cette nouvelle variable et retour (y, z) ». Cela est dû au fait que q est écrit dans une expression de correspondance de motif, juste après with.

C'est aussi la raison pour laquelle vous recevez un avertissement sur la ligne suivante indiquant "Cette règle ne sera jamais mise en correspondance". C'est un malentendu très commun lorsque les gens apprennent F #.

Vous n'utilisez pas vraiment de correspondance de motif du tout lorsque vous faites cela. Donc, je recommande d'utiliser une expression au lieu if:

 if y + z * 10 = q 
     then (y, z) 
     else aux (y + 1, z + 1, q) 

Ceci est en fait équivalent à l'aide des opérateurs ternaires ? et : en C parce qu'il est une expression, pas une déclaration, mais il lit plus clairement.

+0

Merci beaucoup pour votre explication, cela m'a aidé à clarifier le concept. – Worice