Devolviendo una función con un cierre

El siguiente código:

let CreateFunc=
    let counter = ref 0
    fun () -> counter := !counter + 1; !counter

let f1 = CreateFunc
let f2 = CreateFunc

printfn "%d" (f1())
printfn "%d" (f1())
printfn "%d" (f2())
printfn "%d" (f2())

Salidas:

1
2
3
4

So, basically, what we see here is f1 and f2 being the same function - as they're obviously sharing the same instance of 'counter'.

El resultado esperado es:

1
2
1
2

QUESTION: Shouldn't f1 and f2 be two separate instances? After all they are created by the two different calls to 'CreateFunc'???

Muchas Gracias

preguntado el 08 de noviembre de 11 a las 10:11

1 Respuestas

let CreateFunc() =
    let counter = ref 0
    fun () -> counter := !counter + 1; !counter

let f1 = CreateFunc()
let f2 = CreateFunc()

printfn "%d" (f1())
printfn "%d" (f1())
printfn "%d" (f2())
printfn "%d" (f2())

La salida es

1
2
1
2

Explicación:

In your original solution, CreateFunc was a function, but always the same function (CreateFunc, f1 y f2 were all synonyms, all pointing to the same function). In my solution CreateFunc es una función que devuelve un Un nuevo function whenever it is called, thus each function has its own state (i.e. counter).

In short: the original CreateFunc was a value, always the same value.

respondido 08 nov., 11:15

@swapneel - := is the way you assign a value to a reference cell (created with ref 0 in this case). This code uses !counter to read the value out of the reference cell. - Joel Mueller

To elaborate @JoelMueller's answer: since regular let-bindings are immutable, when you do want to use mutable bindings (and let mutable has its disadvantages), you use ref types, which are a bit similar to C/C++ pointers (only a bit). To get their value you can use the ! prefix operator (like in the code !counter) and to assign you can use the binary operator := (line in the code counter := !counter + 1). Nota:: desde counter := !counter + 1 is common, there is an incr function (used incr counter) which increments the int ref by one. - Ramón Snir

To elaborate to @Ramon Snir's answer, ordinary mutables are not allowed in closures, so ref cells must be used here. - Robert Jeppesen

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.