2016-04-20 24 views
5

Voglio leggere alcuni numeri da un file, portarli a una lista e, infine, li visualizza sullo schermo. numbers.txt ha attualmente 2 3 5 7 11 tuttavia come output sto ricevendo 11 7 5 3 2 - : unit =()funzione restituisce la lista in ordine inverso in OCaml

Perché sta succedendo?

let rec int_list_from_sb sb n = 
match n with 
| 0 -> []; 
| _ -> (bscanf sb " %d" (fun a -> a))::(int_list_from_sb sb (n - 1));; 

let file_name = open_in "numbers.txt" in 
let sb = Scanning.from_channel file_name in 
let int_list = int_list_from_sb sb 5 in 
List.iter (fun a -> print_int a) int_list;; 

risposta

5

L'ordine di valutazione degli argomenti non è specificato in OCaml. Così, quando lo fai f x :: g y, è specificato se f o g viene chiamato prima. Nel tuo caso la chiamata ricorsiva viene invocata prima della chiamata a bscanf, motivo per cui ottieni i risultati nell'ordine sbagliato.

Il modo generale per risolvere i problemi relativi all'ordine di valutazione consiste nel mettere gli argomenti in una funzione in variabili locali quando l'ordine dei loro effetti collaterali è importante. Quindi, invece di f x :: g y, dovresti fare let fx = f x in fx :: g y se vuoi che gli effetti di f x avvengano prima che venga chiamato lo g.

Tuttavia nel suo caso si può solo fare uso di argomenti continuazione bscanf s' in questo modo:

bscanf sb " %d" (fun a -> a :: int_list_from_sb sb (n - 1)) 
+0

se sceglie la seconda funzione qui, quella ricorsiva, che cosa succede al numero intero che bscanf ottenuto? –

+0

@power_output Ciò che succede è che 'int_list_from_sb 4' valuta, leggendo 4 numeri da 'sb' e restituendo' [7; 5; 3; 2] ', quindi' bscanf sb "% d" (fun a -> a) 'valuta e restituisce' 11' e poi '11 :: [7; 5; 3; 2] 'viene valutato e restituisce' [11; 7; 5; 3; 2] '. – sepp2k

+0

@power_output Sei stato fortunato, perché il sistema ha appena posticipato la scansione in modo prevedibile. I risultati potrebbero (* in linea di principio *) essere ancora più interessanti, dal momento che 'sb' è una struttura mutevole: immagina cosa succederebbe se entrambe le espressioni fossero valutate, ad esempio, a turno. –