Manipolazione di liste in OCaml
-
10-07-2019 - |
Domanda
Ho problemi a manipolare elenchi profondamente annidati in OCaml nel contesto seguente.
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;;
L'errore che ottengo è, " myList variabile di istanza non associata " ;. Come posso assegnare il risultato di " List.append myList (createListOfElements f # getP) a myList in questo contesto?
Grazie!
Funzione modificata:
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;;
Soluzione
È necessario utilizzare i riferimenti per interrompere la persistenza, poiché la programmazione funzionale utilizza dati persistenti. Usa la parola chiave ref
nella dichiarazione di myList:
let myList = ref (createListOfElements 5)
Per conoscere l'elenco utilizzare !
, quindi la riga in questione diventa
if f#isEven then
myList := !myList @ f#getP;
Ti suggerisco di usare un accumulatore in quanto è nello spirito dello stile di programmazione funzionale, come questo:
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
Modifica
Non ho compilato il mio codice e non ho notato che stai usando il simbolo sbagliato per modificare il valore del riferimento. Il simbolo corretto è : =
. Vedi la mia modifica sopra. Consiglio vivamente di evitare i riferimenti, tuttavia, e di seguire la strada dell'accumulatore.