9

C'è un modo per dichiarare una funzione prima di definirla in OCaml? Sto usando un interprete OCaml.OCaml: dichiarare una funzione prima di definirla

Ho due funzioni:

let myFunctionA = 
(* some stuff here..... *) myFunctionB (*some stuff *) 

let myFunctionB = 
(* some stuff here .... *) myFunctionA (* some stuff *) 

Questo non funziona, però, dal momento che non può chiamare myFunctionA myFunctionB prima che sia fatta.

Ho effettuato alcune ricerche su google ma non riesco a trovare nulla. Come posso realizzare questo?

+0

Parole chiave pertinenti: "ocaml corecursive function". Vedi [Note su OCaml: Funzioni reciprocamente ricorsive] (http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html#Mutually%20recursive%20functions). –

+1

Non posso dire di aver mai sentito la co-ricorsione per implicare una ricorsione reciproca - anche se è abbastanza ovvio cosa significherebbe. – nlucaroni

risposta

21

Ciò che si desidera è rendere reciprocamente ricorsive queste due funzioni. Invece di usare "lasciare ... lasciare che ...", è necessario utilizzare "lasciare rec ... e ..." come segue:

let rec myFunctionA = 
(* some stuff here..... *) myFunctionB (*some stuff *) 

and myFunctionB = 
(* some stuff here .... *) myFunctionA (* some stuff *) 
2

realtà "let rec .." ha un gravissimo limitazione: funziona solo all'interno di un singolo modulo. Questo costringe il programmatore a scrivere grandi moduli dove non è desiderato .. un problema che non si verifica in C poco!

Esistono diversi metodi, tutti insoddisfacenti. Il primo è quello di creare una variabile del tipo di funzione e inizialmente memorizza una funzione sollevando un'eccezione in esso, quindi memorizza in seguito il valore desiderato.

Il secondo consiste nell'utilizzare classi e classi (e un'indirizzamento indiretto). Se hai molte funzioni reciprocamente ricorsive questo è il modo migliore (perché devi solo passare un singolo oggetto a ciascuna di esse).

Il più semplice e il più brutto è passare le funzioni l'un l'altro come argomenti, una soluzione che diventa rapidamente fuori controllo. In un modulo che segue tutte le definizioni è possibile semplificare il codice chiamante introducendo un set di wrapper "let rec". Sfortunatamente, questo non aiuta a definire le funzioni, ed è comune che la maggior parte delle chiamate si verifichi in tali definizioni.

+0

Si noti che questo è ora un po 'facilitato dai moduli ricorsivi, per esempio in questo modo: http://stackoverflow.com/a/33482273/2482998. È comunque piuttosto imbarazzante, comunque. – antron