Pregunta

Actualmente la lectura de una serie de entradas del blog en F #, dirigido al programador de C #. Ahora he terminado de leer parte 3 ( http://www.jelovic.com/weblog/ ? p = 220 ) y me quedo perplejo.

La diferencia entre

dejar que readLine = Console.ReadLine ()

y

dejar que readLine () = Console.ReadLine ()

es lo suficientemente claro, pero ¿por qué existe la necesidad de especificar los dos apoyos (-) - en la siguiente línea:

deje de impresión (texto: string) () = Texto Console.WriteLine

¿No debería el compilador sea capaz de averiguar que está declarando una impresión delegado omitiendo los apoyos, por lo que se vería de la siguiente manera:

deje de impresión (texto: string) = Texto Console.WriteLine

Además, la siguiente línea no tenía mucho sentido para mí

Por lo general, cuando se tiene una función que toma los parámetros de un tipo diferente que el compilador puede diferenciar entre una llamada de función y una referencia delegado, pero para la unidad hay que forzarlo.

¿Quiere esto decir que cuando los parámetros son diferentes que es seguro para que el compilador asume que es una llamada a la función?

gracias a todos por las respuestas, es claro para mí ahora. En cuanto a la cita, vamos a dejar reposar.

¿Fue útil?

Solución

Introducción. Creo que es útil discutir primero la diferencia en el ejemplo sencillo, ya que ayuda a entender lo que significa "unidad" es el valor. La primera declaración crea un valor de cadena (y llama inmediatamente ReadLine para obtener la entrada del usuario):

> let readLine = Console.ReadLine ();;
val readLine : string

La segunda declaración crea una función que toma valor unitario como un argumento. La función no tiene que tomar ninguna entrada, pero queremos definirla como una función, por lo que se puede ejecutar repetidamente (necesitamos que, debido a que la función tiene efectos secundarios - se lee entrada del usuario).

El parámetro "unidad" es simplemente una manera de crear una función que toma algo como argumento. "Unidad" sólo tiene un único valor escrito como (), por lo que no representa ninguna información - sólo el hecho de que hay algún parámetro:

> let readLine () = Console.ReadLine ();;
val readLine : unit -> string

Su pregunta. para mirar su ejemplo con los apoyos adicionales. Esto crea una función que toma una cadena como el primer parámetro y toma un valor adicional "unidad" como el segundo parámetro. Se puede ver que desde la firma de tipo:

> let print (text : string) () = Console.WriteLine text 
val print : string -> unit -> unit

Esto es válido # declaración M, pero no es muy útil. Esto significa que la función se llama solamente cuando usted le da un poco de cuerda para imprimir y también el valor "unidad" adicional. Se le puede llamar así:

print "Hello" ()

Incluso sin el parámetro adicional "unidad", sería una función (en contraposición a un valor), por lo que añadir el parámetro adicional no ayuda (que está siempre creando una función que se puede llamar para imprimir diferentes cadenas ).

Todavía hay casos en que esta declaración puede ser interesante. Por ejemplo, puede llamar a la función, es suficiente con la cadena como parámetro. En este caso, obtendrá una función como el resultado. La función devuelta tomará unidad e imprimirá la cadena:

let f = print "Hello" // doesn't print anything
f ()                  // prints "Hello"
f ()                  // prints "Hello" again!

Por lo tanto, el compilador le permite utilizar valores de "unidad" como cualquier otro valor en el lenguaje. Esto incluye usos que pueden parecer un poco familiarizado (y no muy útil) al principio, pero pueden hacer una buena sensación en algún escenario.

Otros consejos

Este:

let print (text : string) = Console.WriteLine text

crea un método para imprimir como:

print "hi" // prints "hi" in the console

donde:

let print (text : string) () = Console.WriteLine text

produce un método para imprimir una cadena específica como:

let printHi = print "hi" // Does NOT print a string to the console

printHi () // But now this does print "hi" :)
printHi () // And this...

Así que, esencialmente, se trata de una "cadena específica de impresión X a la función de consola" fábrica que el resultado (ex printHi) puede ser reutilizado muchas veces.

Uso currificación,

let makePrinter (text : string) () = Console.WriteLine text

vamos a crear una función que siempre imprime una determinada cadena, por ejemplo

let helloPrinter = makePrinter "hello"

da "hola" simplemente llamando

helloPrinter ()

Por otro lado,

let print (text : string) = Console.WriteLine text

Salidas inmediatamente "texto" si se llama

print "hello"

y retornos (), no una función de tipo unit -> unit como en el primer caso, curry,.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top