Bene, qualcosa noto come parametria ci dice che se consideriamo il sottoinsieme puro di ML (ovvero, nessuna ricorsione infinita refe tutta quella strana roba), non c'è modo di definire una funzione con questo tipo se non quella che restituisce il vuoto elenco.
Tutto è iniziato con l'articolo di Wadler “ Teoremi gratis! ”. Questo documento, in sostanza, ci dice due cose:
- Se consideriamo i linguaggi di programmazione che soddisfano determinate condizioni, possiamo dedurre alcuni teoremi interessanti semplicemente osservando la firma del tipo di una funzione polimorfica (questo si chiama Teorema di parametricità).
- ML (senza ricorsione infinita,
refe tutte quelle cose strane) soddisfa queste condizioni.
Dal teorema Parametricity sappiamo che se abbiamo una funzione f : 'a list -> 'b list, allora per ogni 'a, 'b, 'c, 'de per tutte le funzioni g : 'a -> 'c, h : 'b -> 'dabbiamo:
map h ∘ f = f ∘ map g
(Nota, fa sinistra ha il tipo 'a list -> 'b liste fa destra è 'c list -> 'd list.)
Siamo liberi di scegliere quello che gci piace, quindi lascia 'a = 'ce g = id. Da allora map id = id(facile da dimostrare per induzione sulla definizione di map), abbiamo:
map h ∘ f = f
Ora lascia 'b = 'd = boole h = not. Supponiamo che per alcuni zs : bool listcapiti che succede f zs ≠ [] : bool list. E 'chiaro che map not ∘ f = fnon non regge, perché
(map not ∘ f) zs ≠ f zs
Se il primo elemento dell'elenco a destra è true, allora a sinistra il primo elemento è falsee viceversa!
Ciò significa che la nostra ipotesi è sbagliata e f zs = []. Abbiamo finito? No.
Abbiamo ipotizzato che lo 'bsia bool. Abbiamo dimostrato che quando fviene invocato con type f : 'a list -> bool listper any 'a, fdeve sempre restituire l'elenco vuoto. Può essere che quando chiamiamo fcome f : 'a list -> unit listrestituisce qualcosa di diverso? La nostra intuizione ci dice che questa è una sciocchezza: semplicemente non possiamo scrivere in puro ML una funzione che restituisce sempre la lista vuota quando vogliamo che ci dia un elenco di booleani e che altrimenti potrebbe restituire una lista non vuota! Ma questa non è una prova.
Quello che vogliamo dire è che fè uniforme : se restituisce sempre una lista vuota per bool list, allora deve restituire l'elenco vuoto per unit liste, in generale, qualsiasi 'a list. Questo è esattamente ciò di cui tratta il secondo punto dell'elenco puntato all'inizio della mia risposta.
Il documento ci dice che in ML fdeve prendere relativi valori relativi quelle. Non entrerò nei dettagli delle relazioni, è sufficiente dire che le liste sono correlate se e solo se hanno uguale lunghezza e i loro elementi sono correlati in coppia (cioè, [x_1, x_2, ..., x_m]e [y_1, y_2, ..., y_n]sono correlati se e solo se m = ne x_1sono correlati a y_1ed x_2è correlato y_2e così via). E la parte divertente è, nel nostro caso, poiché fè polimorfica, possiamo definire qualsiasi relazione sugli elementi delle liste!
Prendiamo qualsiasi 'a, 'be guardare f : 'a list -> 'b list. Ora guarda f : 'a list -> bool list; abbiamo già dimostrato che in questo caso frestituisce sempre l'elenco vuoto. Ora postuliamo che tutti gli elementi di 'asono correlati a se stessi (ricordate, possiamo scegliere qualsiasi relazione che vogliamo), questo implica che qualcuno zs : 'a listè legato a se stesso. Come sappiamo, fassume valori correlati a quelli correlati, ciò significa che f zs : 'b listè correlato f zs : bool list, ma il secondo elenco ha una lunghezza pari a zero e poiché il primo è correlato ad esso, è anche vuoto.
Per completezza, menzionerò che c'è una sezione sull'impatto della ricorsione generale (possibile non terminazione) nel documento originale di Wadler, e c'è anche un documento che esplora teoremi liberi in presenza di seq.