2009-10-01 12 views
9

Mi chiedevo solo come sia possibile scrivere una funzione radice quadrata (sqrt) definita dall'utente in modo che interagisca correttamente con il numero unit system di F #.Radici quadrate sicure per le unità

quello che dovrebbe essere simile:

 
let sqrt (x : float<'u^2>) = 
    let x' = x/1.0<'u^2> // Delete unit 
    (x ** 0.5) * 1.0<'u>  // Reassign unit 

Ma questo non è consentito a causa di costanti non nulli non avere il permesso di avere unità generiche.

C'è un modo per scrivere questa funzione? Con l'integrato sqrt funziona bene, quindi che magia esegue?

+1

Domanda correlata: (risposta anche da @kvb) http://stackoverflow.com/questions/1398611/f-ununit-reunit-inside-a-function – Benjol

risposta

6

Consentire costanti generiche diverse da zero renderebbe molto facile rompere la sicurezza del sistema di tipi per unità (vedere Andrew Kennedy's papers). Credo che la risposta alla tua ultima domanda sia che sqrt è davvero magico in un certo senso in quanto non dovrebbe essere possibile definire una funzione parametrica con quel tipo di firma attraverso mezzi normali. Tuttavia, è possibile fare ciò che si vuole (almeno nella versione attuale di F #), approfittando di boxe e casting:

let sqrt (x : float<'u^2>) = 
    let x' = (float x) ** 0.5 (* delete unit and calculate sqrt *) 
    ((box x') :?> float<'u>) 
6

@kvb è giusto, più in generale:

Se si dispone di un algoritmo non di unità (ad esempio, si scrive "radice cubica") e si desidera posizionare unità su di esso, è possibile avvolgere l'algoritmo in una funzione con la firma del tipo giusto e utilizzare ad esempio "fluttuare" per "scacciare" le unità mentre entrano e l'approccio "a scatola e croce" per "rimontare" le unità appropriate in uscita.

Nella versione RTM (dopo Beta2), F # avrà le funzioni di libreria primitive per le "unità add-back", dal momento che l'approccio box-and-downcast è attualmente un bit di un hack per superare la mancanza di questi primitivi in la lingua/biblioteca

+0

Grazie - Potresti nominare queste nuove funzioni di libreria (Link)? – Dario

+3

Probabilmente saranno chiamati per es. "val inline FloatWithMeasure: float -> float <'u>" nel modulo LanguagePrimitives. – Brian

+0

E qui è: http://msdn.microsoft.com/en-us/library/ee806527(VS.100).aspx – Benjol

Problemi correlati