Question

Dans le MiniCsvTypeProvider, je vois la ligne de code suivante :

        let prop = ProvidedProperty(fieldName, fieldTy, GetterCode = fun [row] -> <@@ (%%row:float[]).[i] @@>)

avec le type GetterCode est : Liste Quotations.Expr -> Quotations.Expr :

Je ne sais pas vraiment ce que le lambda amusant fait....

  • il fait correspondre son entrée avec un tableau d'éléments uniques, en le liant à une variable nommée 'row' , de type Quotations.Expr à partir de la signature GetterCode.

  • il crée une citation de code en retour

  • à l'intérieur de la citation de code, il utilise %%row:float[] et je ne sais pas ce que cela signifie : est-ce une contrainte de type Float [] pour les citations de code non typées ?
Était-ce utile?

La solution

La réponse de Jack est correcte.J'ajouterai un peu plus de contexte. (%%) est l'opérateur d'épissage non typé (c'est-à-dire qu'il épisse un Quotations.Expr dans une autre citation tapée ou non), tandis que (%) est l'opérateur d'épissage typé (c'est-à-dire qu'il épisse un Quotations.Expr<'t> pour certains 't dans une autre citation tapée ou non). (a : ty) est juste une annotation de type, donc (%%row : float[]) indique que lorsque row est intégré à la citation, le résultat est un float[].Sans cette annotation, %%row pourrait être une valeur de n’importe quel type, et le compilateur serait incapable de déduire ce que nous entendons par .[] indexeur (tout comme il ne peut pas déduire le type de arr dans fun arr i -> arr.[i]).

Au cas où cela pourrait être utile, voici quelques façons alternatives d'exprimer à peu près la même chose que <@@ (%%row:float[]).[i] @@>:

  • Nous pouvons convertir la citation non typée en citation typée avant l'épissage :

    let typedRow = Quotations.Expr.Cast<float[]> row 
    <@@ %typedRow.[i] @@>
    

    Ici, nous utilisons l'opérateur d'épissure typé (%), donc le compilateur sait que %typedRow est un float[] et que le .[] l’opérateur est applicable.

  • Nous pouvons utiliser une manière différente d'indexer dans le tableau afin que l'inférence de type de F# puisse déterminer le type de %%row sans annotation :

    <@@ Array.get %%row i : float @@>
    

    Ici le Array.get la méthode prend un 'a[] comme argument et nous ajoutons une annotation de type qui indique que le résultat est un float, donc F# déduira que %%row est un float[].

Autres conseils

Le: float [] est une annotation de type explicite (non contrainte, qui est similaire mais différente);Il dise %% la ligne produira une valeur de type float [].

Puis, en l'enveloppant entre parenthèses, vous pouvez utiliser la syntaxe. [IDX] pour obtenir un élément du tableau car le compilateur F # déduit le type de valeur dans la parenthèse comme float [].

spécifiant explicitement une annotation de type de cette façon peut être un moyen utile de donner au compilateur F # un "indice" et de résoudre des erreurs d'inférence de type.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top