da apatriarca » 26/01/2015, 21:50
Facendo qualche semplificazione, quelle funzioni possono essere tranquillamente riscritte in forma matematica come normali funzioni tra insiemi. Ad ogni tipo corrisponde un insieme di valori e puoi in generale avere insiemi arbitrari (a cui quindi associ un nome fittizio) e insiemi specifici come quello degli interi.
In particolare, la funzione \(f\) del primo esercizio potrebbe essere riscritta nel seguente modo come funzione matematica:
\[ f(x, y, z, t) = z\bigl(x, t(y)\bigr). \]
È qui chiaro che \(x\) e \(y\) possono appartenere ad insiemi qualsiasi, mentre \(z\) è una funzione con due variabili e \(t\) con una. A quel punto associ alle due variabili libere \(x\) e \(y\) tipi qualsiasi 'a e 'b. Prendi quindi in considerazione \(t\) (che a questo punto non dipende da alcun tipo non definito) e osservi che è una funzione la cui immagine può essere arbitraria. Dai quindi il nome 'c a questo insieme arbitrario. Infine osservi che \(z\) prende come argomenti \(x\) e l'immagine di \(y\) attraverso \(t\) per cui avrà tipo 'a -> 'c -> 'd per un insieme 'd arbitrario.
La funzione f3 ha ad esempio la forma
\[ f_3(y, x) = x\bigl(y(x)\bigr). \]
In questo caso hai quindi che \(x\) è una funzione che ha come argomento il valore di ritorno di \(y\) che a sua volta ha come argomento un valore dello stesso tipo di \(x\). Se quindi supponi che \(x\) abbia tipo 'a -> 'b, \(y\) dovrà avere tipo ('a -> 'b) -> 'a. Da qui dovrebbe essere facile ottenere quindi il tipo di f3.
I casi in cui usi List.filter o List.map sono simili. Devi semplicemente ricordarti il tipo di queste funzioni e usarle per capire il tipo totale delle espressioni.
È utile comunque provare a testare queste funzioni in Ocaml direttamente per vedere come si comportano. Per esempio, nel caso di f3 puoi supporre che \(y\) sia ad esempio una funzione che ignora il suo argomento e restituisce un valore costante. f3 restituirà allora il valore di \(x\) per questo valore costante. Se invece y restituisse un valore \(v\) per cui \(x(v)\) assume un massimo, f3 restituirà questo valore massimo. Scrivendo programmi si imparano ad usare con successo funzioni più complicate e diventa quindi poi anche più facile interpretarle.