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;;
¿Fue útil?

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.

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