2010-04-19 6 views
0

Quelqu'un pourrait-il s'il vous plaît me montrer pourquoi la fonction ci-dessous attend entier [] au lieu de l'octet []Pourquoi cette fonction f # Renvoie un entier [] au lieu de tableau d'octets

type Node = 
    | InternalNode of int*Node*Node 
    | LeafNode of int * byte 

let weight node = 
    match node with 
    |InternalNode(w,_,_) -> w 
    |LeafNode(w,_)-> w 

let createNodes inputValues = 
    let getCounts (leafNodes:(int*byte)[])= 
     inputValues |>Array.iter 
      (fun b-> let (w,v) =leafNodes.[(int)b] 
        leafNodes.[(int)b]<-(w+1,v)) 

     leafNodes 
    [|for b in 0uy..255uy -> (0 ,b)|] |>getCounts 
    |>List.ofArray 
    |>List.map LeafNode 

Répondre

6

Le seul endroit qui indique le F # compilateur quelque chose sur le type du paramètre est dans la fonction lambda donnée à Array.iter (à partir de l'utilisation de cette fonction d'ordre supérieur, le compilateur déduit que vous travaillez avec des tableaux). A l'intérieur de la fonction lambda que vous avez:

leafNodes.[(int)b] 

Comme un côté note, int dans ce code est juste une fonction normale F # (et non une construction en fonte de type spécial), donc de la manière habituelle d'écrire serait juste:

leafNodes.[int b] 

maintenant, le compilateur sait que b (qui est, les valeurs du tableau donné comme argument) peuvent être convertis en entier, mais la fonction int travaille avec d'autres types (vous pouvez écrire par exemple int 3.13f. Dans des cas ambigus comme celui-ci, le compilateur utilise int comme type par défaut, c'est la raison pour laquelle vous voyez un type int[].

Vous pouvez ajouter des annotations de type à la déclaration comme celui-ci (et cela fonctionnera sans aucun autre changement, car byte peut être converti en entier en utilisant la fonction int):

let createNodes (inputValues:byte[]) = 
    // ... 
+0

Grande explication de l'auteur du meilleur livre de f #. thanx :) –

+0

@accidental coder: Merci (pour les deux compliments)! –

Questions connexes