2016-08-29 4 views
1

En F # J'ai un très long fichier de code commeénorme fichier de Split F # avec des fonctions mutuellement récursives

let rec f1 a1 a2 a3 a4 a5 .. aN = 
      ... 

    and f2 a1 a2 a3 a4 a5 ... aN = 
      ... 
    and f3 a1 a2 a3 a4 a5 ... aN = 
      ... 



    and f40 a1 a2 a3 a4 a5 ... aN = 
      ... 

En d'autres termes, il existe de nombreuses fonctions mutuellement récursives, chacun avec un grand nombre de paramètres.

Maintenant, le problème est que le fichier est 17000 lignes, et Visual Studio est devenu trop lent. (Par exemple, je ne peux pas passer la souris sur un élément pour voir son type, si j'appuie sur le point, il n'y a pas d'achèvement, etc.)

Par conséquent, je dois diviser le fichier en plusieurs petits fichiers. Mais je ne peux pas voir une façon mécanique et facile de le faire.

Pourriez-vous me donner un conseil? Je voudrais un moyen mécanique pour diviser le code en plusieurs fichiers, ce qui n'implique pas d'écrire le type de toutes les fonctions (préserver l'inférence de type).

+0

Si vous avez 'laisser ... et ...' il doit tous être dans le même fichier –

+0

bien sûr, mais il doit y avoir un moyen de réécrire le code de manière à le diviser. Déclarez un type de fonction avant de déclarer le corps de la fonction, quelque chose comme ça. Si je dois le faire seulement pour une ou deux fonctions, c'est bon. – seguso

+0

Ne peut pas être fait, F # n'a rien à voir avec les fichiers d'en-tête. –

Répondre

1

En attendant, je trouve une solution (testé):

Ceci est la situation initiale (simplifiée pour avoir seulement quatre fonctions, mais en réalité ils sont beaucoup plus):

let rec f1 a b c = 

      f2 a b c; 
      f3 a b c; 
      f4 a b c; 



    and f2 a b c = 

      f1 a b c; 
      f3 a b c 
      f4 a b c 

    and f3 a b c = 

      f1 a b c; 
      f2 a b c 
      f4 a b c 


    and f4 a b c = 
      f1 a b c; 
      f2 a b c 
      f3 a b c 

Et ici est la solution:

Supposons que vous décidiez de déplacer f3 dans un autre fichier. Ensuite, vous pouvez diviser le fichier ci-dessus dans deux fichiers comme suit:

FILE 1 
    ====== 


    let callRef mf = 
      match !mf with 
      | None -> failwith "function ref is none" 
      | Some f -> f 

    let r_f3 = ref None; 

    let rec f1 a1 a2 a3 = 

      f2 a b c; 
      callRef r_f3 a1 b1 c1; 
      f4 a1 b1 c1; 



    and f2 a1 a2 a3 = 

      f1 a b c; 
      callRef r_f3 a1 b1 c1; 
      f4 a1 b1 c1; 



    and f4 a1 a2 a3 = 
      f1 a b c; 
      f2 a1 b1 c1; 
      callRef r_f3 a1 b1 c1; 





    FILE 2 
    ====== 

    let f3 a1 a2 a3 = 

      f1 a b c; 
      f2 a1 b1 c1;        
      f4 an bn cn; 

Puis, dans la fonction principale d'initialisation (qui est dans un troisième fichier), vous devez faire

r_f3 := Some f3; 

Et c'est tout.

Répétez la même stratégie pour déplacer f1, f2 et f4 du premier fichier.

Mise à jour: Cette solution fonctionne bien pour les fonctions qui retournent l'unité, mais malheureusement pour les fonctions qui renvoient un type réel, elle vous oblige à spécifier le type de fonction explicitement, par ex.

let (r_f3 : (t1 -> t2 -> t3 -> t4 -> t5) option ref) = ref None; 

ou vous pouvez le faire:

let (r_f3 : 'a option ref) = ref None; 

mais vous obtiendrez un avertissement du compilateur.