2012-06-28 12 views
5

entiendo la garrapata para significar un parámetro genérico, como en:¿Cuál es la diferencia entre el significante genérico "y el símbolo^en F # Método de firmas

Seq.append : seq<'T> -> seq<'T> -> seq<'T> 

pero ¿qué significa el símbolo de intercalación, como en:

Seq.average : seq<^T> -> ^T 
+2

''' se resuelven en tiempo de ejecución (genéricos); '^' se resuelven en tiempo de compilación. Consulte [Parámetros de tipo resueltos estáticamente] (http://msdn.microsoft.com/en-us/library/dd548046.aspx). – ildjarn

+0

ildjarn, ¿por qué no agregarías esto como respuesta y no como comentario? Me parece correcto. –

+0

Porque simplemente el enlace a la documentación sin agregar detalles hace una respuesta pobre, y no tengo ganas de agregar detalles en este momento. ; -] – ildjarn

Respuesta

5

La firma detallado es:

Seq.average: SEQ <^T> ->^T (requiere^T con el miembro estático (+) y^T con el miembro estático DivideByInt y^T con miembro estático cero)

a diferencia de Seq.append, Seq.average necesita más restricciones en el tipo de elementos. En particular:

       _ DivideByInt (s1 + s2 + ... + sn) n where n <> 0 
Seq.average {s1; s2;...; sn} =/
           \_ ^T.Zero where n = 0 

Como se puede ver, tanto (+), DivideByInt y Zero se requieren con el fin de que Seq.average<^T> tiene sentido.

Se puede encontrar información útil sobre los genéricos hereMSDN.

+0

Gracias por la aclaración. Lo eliminé para acortar el ejemplo y no debería haberlo hecho. –

6

el símbolo de intercalación indica que el parámetro de tipo debe ser resuelto de forma estática, por lo general, porque hay limitaciones particulares sobre el tipo que debe ser satisfecha y que no puede ser expresado en los metadatos normal de .NET. Por ejemplo, no puede llamar al Seq.average "test" aunque "test" es un seq<char>, porque char s no son compatibles con las operaciones aritméticas necesarias.

Estas variables de tipo resueltas estáticamente solo surgen de las definiciones inline, y cuando se utiliza dicha función, su cuerpo está en línea para que el compilador pueda insertar las instrucciones correctas específicas del tipo.

+0

Podría ser bueno dar una nota rápida sobre el apóstrofo. No es necesario un montón de detalles, pero es útil para las personas que no saben mucho sobre los genéricos. – Guvante

0

Aunque, como otros han señalado, por convención ^T se utiliza con inline y 'T no es, los dos son intercambiables (a veces?).

Por lo tanto, técnicamente, la respuesta a su pregunta es "no hay ninguna diferencia".

kvb señaló: hay es una diferencia. Pero no es tan claro como indican las otras respuestas. En algunos casos, los dos son intercambiables, por ejemplo,

let inline add (x:^T) (y:^T) = x + y 
let inline add (x:'T) (y:'T) = x + y 

o

let f (x:^T) = !x 
let f (x:'T) = !x 

La convención es claro, mientras que la aplicación no lo es.

+0

No creo que sea correcto, mira lo que sucede si tratas de ejecutar 'let f (x:^t) = x' y' let f (x: 't) = x'. – kvb

+0

Estoy confundido acerca del efecto de '^'. Esto funciona de la misma manera: 'let add (x:^T) (y:^T) = x + y'. – Daniel

+0

Esto también funciona: 'let f (x:^t) = x * x' – Daniel

Cuestiones relacionadas