Manipulación de listas en OCaml
-
10-07-2019 - |
Pregunta
Tengo problemas para manipular listas profundamente anidadas en OCaml en el contexto siguiente.
class foo (pIn:int)=
object (self)
val p = pIn
val even = if (pIn mod 2) = 0 then true else (false)
method doIt = "doIt"
method isEven = even
method getP = p
end;;
let rec createListOfElements howMany = (
Random.self_init ();
if howMany > 1 then ((new foo (Random.int 10))::(createListOfElements (howMany - 1)))
else ([(new foo (Random.int 10))]) );;
let myList = createListOfElements 5;;
let rec process1 param =
if param <= 10 then
let f = new foo param in (
if f#isEven then (myList <- List.append myList (createListOfElements f#getP));
Printf.printf "%s\n" f#doIt;
process1 (param+1) )
in process1 0;;
El error que obtengo es "Variable de instancia independiente myList". ¿Cómo hago para asignar el resultado de " List.append myList (createListOfElements f # getP) a myList en este contexto?
¡Gracias!
Función editada:
let myList = ref (createListOfElements 5);;
let rec process1 param =
if param <= 10 then
let f = new foo param in (
if f#isEven then (myList <- !myList @ (createListOfElements f#getP));
Printf.printf "%s\n" f#doIt;
process1 (param+1) )
in process1 0;;
Solución
Debe usar referencias para romper la persistencia, ya que la programación funcional usa datos persistentes. Use la palabra clave ref
en la declaración de myList:
let myList = ref (createListOfElements 5)
Para eliminar la referencia de la lista, use !
, de modo que la línea en cuestión se vuelva
if f#isEven then
myList := !myList @ f#getP;
Le sugiero que use un acumulador ya que está en el espíritu del estilo de programación funcional, como este:
let rec process1 lst = function
| x when x <= 10 ->
let f = new foo x in
if f#isEven then
process1 (lst @ (createListOfElements f#getP)) (param+1)
else
process1 lst (param+1)
| _ -> lst
EDIT:
No compilé mi código y no noté que está usando el símbolo incorrecto para cambiar el valor de la referencia. El símbolo correcto es, : =
. Vea mi cambio arriba. Sin embargo, le sugiero que evite las referencias y siga la ruta del acumulador.