2012-03-20 24 views
7

Sono nuovo in Ocaml, voglio solo assicurarmi come eseguire una semplice funzione come restituire l'ennesimo elemento di una lista usando la funzione ricorsiva?restituisce l'ennesimo elemento di una lista in OCaml?

prototipo come get_nth (list, n) con int list * int -> int

ad esempio get_nth ([1,2,3], 1) -> 2

Grazie

+1

Questo sembra davvero un problema di compiti a casa. Sarebbe utile se mostrassi del codice che hai provato che non funziona come speravi. –

risposta

11

Non è possibile notare ma la funzione List.nth è già presente in List module.

Se si desidera scrivere utilizzando la ricorsione:

let rec get_nth = function 
    | [], _ -> raise (Failure "get_nth") 
    | _, n when n < 0 -> raise (Invalid_argument "get_nth") 
    | x::_, 0 -> x 
    | x::xs, n -> get_nth(xs, n-1) 
+0

@VictorNicollet: Grazie per la modifica. – pad

4

utilizza tuple come parametri come questo non è comune in OCaml. Di solito si usa accattivarsi e definire la funzione in questo modo:

let get_nth list n = ... 

Ciò avrebbe la firma 'a list -> int -> 'a. Nota anche che qui hai un parametro 'a, il che significa che non esiste un vero motivo per limitare la tua funzione agli int solo.

Ora diamo un'occhiata al problema. Se vuoi ottenere l'elemento zeroth, quale sarebbe la tua funzione?

let get_nth list 0 = List.head list (* this is not actually valid in OCaml *) 

ora se si dispone di una funzione per ottenere l'elemento n-esimo da un elenco di elementi m (NB n> m), come hai potuto utilizzare tale funzione per costruire un'altra funzione che ottiene il n + 1 ° elemento da un lista di m + 1 elementi? Lasciate che la funzione di n + 1 elementi essere get_nth'

let get_nth' list n' = get_nth (List.tail list) (n'-1) 

Ora tutto quello che dovete fare è quello di combinare le due cose e si è fatto. Lascerò l'ultima parte a te.

Se segui questo consiglio, otterrai qualcosa che è più complicato di quanto debba essere. Tuttavia è più facile capire cosa sta succedendo in questo modo.

+0

Purtroppo, temo che il tuo tentativo sia più confusionario di quanto debba essere. La corrispondenza del modello Ocaml è abbastanza esplicativa da sola. – PieOhPah

3

(a mio parere) Una soluzione più semplice senza l'utilizzo di una tupla può essere:

let rec get_nth mylist index = match mylist with 
    | [] -> raise (Failure "empty list") 
    | first::rest -> 
     if index = 0 then first 
     else get_nth rest (index-1) 
;; 
+1

Avrei fatto la risposta corretta. Usare la tupla come argomento nella funzione Ocaml non è molto idiomatico e richiede allocazione. – PieOhPah

0

ho letto here che l'utilizzo di Result invece di aumentare l'errore può essere più bello dal momento che non è necessario utilizzare uno try ... with. (Codice modificato da @Omar Mahili)

let rec get_nth mylist index = match mylist with 
    | [] -> Error "empty list" 
    | first::rest -> 
     if index = 0 then Ok first 
     else get_nth rest (index-1) 
;; 

let result [1; 2; 3] 2 in 
    match result with 
    | Error reason -> print_string reason 
    | Ok num -> print_int num 
;; 

Result fa parte di Core.Std, se sono corrette.

Problemi correlati