Domanda

In MinicsVtypeProvider, vedo la seguente riga di codice:

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

con il tipo di code getter è: Quotations.expr Elenco -> Quotations.expr :

Non so davvero cosa la lambda divertimento sta facendo....

  • Abbina il suo input con un array di singoli elementi, che lo leghi a una variabile denominata "riga", delle citazioni di tipo.expr dalla firma GetTerCode.

  • Crea una citazione di codice in cambio

  • All'interno della citazione del codice, usa %% riga: float [] e non so cosa significhi: È un vincolo di tipo float [] per citazioni di codice non tipite?
È stato utile?

Soluzione

La risposta di Jack è corretta. Aggiungerò un po 'più di contesto. (%%) è l'operatore di giunzione non tipizzato (cioè giunge a Quotations.Expr in un'altra citazione digitata o non tipita), mentre (%) è l'operatore di giunzione digitato (cioè giunta a Quotations.Expr<'t> per alcuni 't in un'altra citazione digitata o non tipita). (a : ty) è solo un'annotazione di tipo, quindi (%%row : float[]) indica che quando row è giuntato nella citazione il risultato è un float[]. Senza questa annotazione, %%row potrebbe essere un valore di qualsiasi tipo e il compilatore non sarebbe in grado di dedurre cosa intendiamo con .[] indicizzatore (proprio come non può dedurre il tipo di arr in fun arr i -> arr.[i]).

Nel caso sia utile, ecco alcuni modi alternativi per esprimere all'incirca la stessa cosa di <@@ (%%row:float[]).[i] @@>:

  • Possiamo convertire la citazione non tipita in una citazione tipizzata prima di girare:

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

    Qui stiamo usando l'operatore di giunzione digitato (%), quindi il compilatore lo sa %typedRow è un float[] e quello il .[] L'operatore è applicabile.

  • Possiamo usare un modo diverso di indicizzare nell'array in modo che l'inferenza del tipo di F#possa determinare il tipo di %%row Senza un'annotazione:

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

    Qui, il Array.get Il metodo prende un 'a[] Come argomento e aggiungiamo un'annotazione di tipo che indica che il risultato è un galleggiante, quindi F# lo dedicherà %%row è un float[].

Altri suggerimenti

Il: float [] è un tipo di annotazione esplicita (non vincolo, che è simile ma diverso); Sta dicendo che %% riga produrrà un valore di tipo float [].

Quindi avvolgendolo tra parentesi, è possibile utilizzare la sintassi. [Idx] per ottenere un elemento dell'array perché il compilatore F# influisce il tipo di valore all'interno della parentesi come float [].

Specificare esplicitamente un tipo di annotazione in questo modo può essere un modo utile per dare al compilatore F# un "suggerimento" e risolvere errori di inferenza del tipo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top