2009-10-01 11 views
9

Me preguntaba cómo es posible escribir una función de raíz cuadrada definida por el usuario (raíz cuadrada) de una manera que interactúa adecuadamente con F # 's unit system.raíces cuadradas Unidad de fallos

Lo que debería ser como:

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

Pero esto es rechazado debido a constantes distintas de cero no está permitido tener unidades genéricas.

¿Hay una manera de escribir esta función? Con el built-in sqrt funciona bien, entonces ¿qué magia hace?

+1

Pregunta relacionada: (también respondida por @kvb) http://stackoverflow.com/questions/1398611/f-ununit-reunit-inside-a-function – Benjol

Respuesta

6

Permitir constantes genéricas distintas de cero haría muy fácil romper la seguridad del sistema de tipo para las unidades (ver Andrew Kennedy's papers). Creo que la respuesta a su última pregunta es que sqrt es mágico en cierto sentido, en el sentido de que no debería ser posible definir una función paramétrica con esa firma de tipo a través de medios normales. Sin embargo, es posible hacer lo que quiere (al menos en la versión actual de F #) mediante el aprovechamiento de boxeo y de calidad:

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

@kvb es correcto, de manera más general:

Si tiene un algoritmo que no es de unidad consciente (por ejemplo, dice que escribe 'raíz de cubo'), y desea colocar unidades en él, puede envolver el algoritmo en una función con la firma de tipo correcta y usar, por ejemplo "flotar" para "arrojar" las unidades a medida que ingresan y el enfoque de "box-and-downcast" para "volver a agregar" las unidades apropiadas en el camino de salida.

En la versión RTM (después de Beta2), F # tendrá funciones de biblioteca primitivas para las 'unidades de adición', ya que el enfoque de caja y downcast es actualmente un truco para superar la falta de estas primitivas en el lenguaje/biblioteca.

+0

Gracias - ¿Podría nombrar estas nuevas funciones de la biblioteca (Enlace)? – Dario

+3

Probablemente se nombrarán, p. "val FloatWithMeasure en línea: float -> float <'u>" en el módulo LanguagePrimitives. – Brian

+0

Y aquí está: http://msdn.microsoft.com/en-us/library/ee806527(VS.100).aspx – Benjol

Cuestiones relacionadas