2011-04-02 5 views
1

Je suis en train de tester le code suivant pour remplir un dictionnaire de manière récursive. Cependant l'inférence de type ne semble pas reconnaître le type de dictionnaire. J'ai essayé d'utiliser une annotation de type mais cela n'a pas semblé aider.Remplir un dictionnaire de manière récursive?

Y at-il des restrictions sur l'utilisation des dictionnaires dans une routine récursive. Ai-je besoin de rendre le dictionnaire modifiable puisque je m'attends à le changer pendant les itérations.

open System 
open System.Collections.Generic 

////dictionary recursion test 

let pop_dict tlist = 
    // let rec inner tlist acc ddict:Dictionary<string,int> = 
    let rec inner tlist acc ddict = 
     match tlist with 
      | [] -> ddict.Add ("dummykey", acc)        
      | x::xs -> inner xs (x::acc) ddict 
    let ddict = Dictionary<string,int>() 
    inner tlist [] ddict 


// Main Entry Point 
let main() = 

    let tlist = [1;2;3;4] 
    let d = pop_dict tlist 

main() 
+0

Vous voulez un dictionnaire mutable avec une clé (« dummyKey ») qui contient la liste que vous avez passé dans? Soit dic = Dictionary (); dic.add ("dummykey", [1,2,3,4]) –

Répondre

4

Tout d'abord, vos types ne correspondent pas.

Vous essayez d'ajouter un int list (qui est ce que acc est) à un dictionnaire qui est censé contenir int s.

En dehors de cela, cependant, la raison pour laquelle le compilateur ne peut pas déduire le type de ddict est. Rappelez-vous, lorsque le vérificateur de type détermine les types pour la fonction, il ne regarde pas ce qu'il est appelé par la suite. Il ne dispose des informations suivantes:

let rec inner tlist acc ddict = 
    match tlist with 
     | [] -> ddict.Add ("dummykey", acc)        
     | x::xs -> inner xs (x::acc) ddict 

Cela signifie que la seule information qu'il connaît ddict quand il compile la fonction, est qu'il a une méthode nommée Add, qui string * 'a list -> ?.

Pour résoudre ce problème, changer

let rec inner tlist acc ddict = 

à

let rec inner tlist acc (ddict:Dictionary<string,int>) = 

Vous avez toujours le problème avec les types de désadaptation sur cependant, le dictionnaire, vous voulez probablement être Dictionary<string, int list>, si vous plan sur le stockage int list s dedans.

+0

Bonne explication - obtenir/vérifier les règles de vérification de type est peut-être la partie la plus délicate de l'apprentissage F # - mais il concentre l'esprit et (espérons-le) améliore nos compétences de codage. – BrendanC

1

est ce que vous vouliez?

let pop_dict tlist = 
    let rec inner tlist acc (ddict:Dictionary<string,int list>) = 
     match tlist with 
      | [] -> ddict.Add ("dummykey", acc)        
      | x::xs -> inner xs (x::acc) ddict 
    let ddict = Dictionary<string,int list>() 
    inner tlist [] ddict 


// Main Entry Point 
let main() = 

    let tlist = [1;2;3;4] 
    let d = pop_dict tlist 
    () 
Questions connexes