Inferencia de tipos
En este tema se describe cómo el compilador de F# deduce los tipos de valores, variables, parámetros y valores devueltos.
Inferencia de tipos en General
La idea de la inferencia de tipos es que no es necesario especificar los tipos de construcciones de F#, excepto cuando el compilador no puede deducir el tipo de forma concluyente. La omisión de información de tipo explícita no significa que F# sea un lenguaje con tipo dinámico o que los valores de F# estén débilmente tipos. F# es un lenguaje con tipo estático, lo que significa que el compilador deduce un tipo exacto para cada construcción durante la compilación. Si no hay suficiente información para que el compilador deduzca los tipos de cada construcción, debe proporcionar información de tipo adicional, normalmente agregando anotaciones de tipo explícitas en algún lugar del código.
Inferencia de tipos de parámetro y valor devuelto
En una lista de parámetros, no es necesario especificar el tipo de cada parámetro. Sin embargo, F# es un lenguaje con tipo estático y, por tanto, cada valor y expresión tiene un tipo definido en tiempo de compilación. Para los tipos que no se especifican explícitamente, el compilador deduce el tipo en función del contexto. Si el tipo no se especifica de otro modo, se deduce que es genérico. Si el código usa un valor de forma incoherente, de forma que no hay ningún tipo inferido único que satisfaga todos los usos de un valor, el compilador notifica un error.
El tipo de valor devuelto de una función viene determinado por el tipo de la última expresión de la función.
Por ejemplo, en el código siguiente, se deduce que los tipos de parámetro y y el tipo de valor devuelto son porque el a literal es de tipo b int 100 int .
let f a b = a + b + 100
Puede influir en la inferencia de tipos cambiando los literales. Si realiza la operación anexando el sufijo , los tipos de , y el valor devuelto se 100 uint32 u a b deducen como uint32 .
También puede influir en la inferencia de tipos mediante otras construcciones que implican restricciones en el tipo, como funciones y métodos que funcionan solo con un tipo determinado.
Además, puede aplicar anotaciones de tipo explícitas a parámetros de función o método o a variables en expresiones, como se muestra en los ejemplos siguientes. Los errores se producen si se producen conflictos entre restricciones diferentes.
// Type annotations on a parameter.
let addu1 (x : uint32) y =
x + y
// Type annotations on an expression.
let addu2 x y =
(x : uint32) + y
También puede especificar explícitamente el valor devuelto de una función proporcionando una anotación de tipo después de todos los parámetros.
let addu1 x y : uint32 =
x + y
Un caso común en el que una anotación de tipo es útil en un parámetro es cuando el parámetro es un tipo de objeto y desea usar un miembro.
let replace(str: string) =
str.Replace("A", "a")
Generalización automática
Si el código de función no depende del tipo de un parámetro, el compilador considera que el parámetro es genérico. Esto se denomina generalización automática y puede ser una ayuda eficaz para escribir código genérico sin aumentar la complejidad.
Por ejemplo, la función siguiente combina dos parámetros de cualquier tipo en una tupla.
let makeTuple a b = (a, b)
Se deduce que el tipo es
'a -> 'b -> 'a * 'b
Información adicional
La inferencia de tipos se describe con más detalle en la especificación del lenguaje F#.