Nah, sesuatu yang dikenal sebagai parametrik memberi tahu kita bahwa jika kita menganggap subset murni ML (yaitu, tidak ada rekursi tak terbatas, ref
dan semua hal aneh), tidak ada cara untuk mendefinisikan fungsi dengan tipe ini selain yang mengembalikan yang kosong daftar.
Ini semua dimulai dengan makalah Wadler “ Teorema gratis! ” Makalah ini, pada dasarnya, memberi tahu kita dua hal:
- Jika kita mempertimbangkan bahasa pemrograman yang memenuhi kondisi tertentu, kita dapat menyimpulkan beberapa teorema keren hanya dengan melihat tipe tanda tangan dari fungsi polimorfik (ini disebut Parametricity Theorem).
- ML (tanpa rekursi tak terbatas,
ref
dan semua hal aneh itu) memenuhi kondisi itu.
Dari Parametricity Teorema kita tahu bahwa jika kita memiliki fungsi f : 'a list -> 'b list
, maka untuk semua 'a
, 'b
, 'c
, 'd
dan untuk semua fungsi g : 'a -> 'c
, h : 'b -> 'd
kita memiliki:
map h ∘ f = f ∘ map g
(Catatan, f
di sebelah kiri memiliki tipe 'a list -> 'b list
dan f
di sebelah kanan adalah 'c list -> 'd list
.)
Kita bebas memilih apa pun yang g
kita suka, jadi mari 'a = 'c
dan g = id
. Sekarang karena map id = id
(mudah dibuktikan dengan induksi pada definisi map
), kami memiliki:
map h ∘ f = f
Sekarang biarkan 'b = 'd = bool
dan h = not
. Mari kita asumsikan untuk beberapa zs : bool list
hal itu terjadi f zs ≠ [] : bool list
. Hal ini jelas bahwa map not ∘ f = f
tidak tidak tahan, karena
(map not ∘ f) zs ≠ f zs
Jika elemen pertama dari daftar di sebelah kanan adalah true
, maka di sebelah kiri elemen pertama adalah false
dan sebaliknya!
Ini artinya, anggapan kita salah dan f zs = []
. Sudahkah kita selesai? Tidak.
Kami berasumsi bahwa 'b
adalah bool
. Kami telah menunjukkan bahwa ketika f
dipanggil dengan tipe f : 'a list -> bool list
untuk apa pun 'a
, f
harus selalu mengembalikan daftar kosong. Mungkinkah ketika kita memanggil f
karena f : 'a list -> unit list
mengembalikan sesuatu yang berbeda? Intuisi kita memberi tahu kita bahwa ini omong kosong: kita tidak bisa menulis dalam ML murni suatu fungsi yang selalu mengembalikan daftar kosong ketika kita ingin memberi kita daftar boolean dan mungkin mengembalikan daftar yang tidak kosong kalau tidak! Tapi ini bukan bukti.
Apa yang ingin kita katakan adalah bahwa f
adalah seragam : jika selalu mengembalikan daftar kosong untuk bool list
, maka harus mengembalikan daftar kosong untuk unit list
dan, secara umum, setiap 'a list
. Inilah tepatnya poin kedua dalam daftar peluru di awal jawaban saya.
Makalah ini memberitahu kita bahwa di ML f
harus mengambil terkait nilai-nilai ke terkait yang. Saya tidak akan merinci tentang hubungan, cukup untuk mengatakan bahwa daftar terkait jika dan hanya jika mereka memiliki panjang yang sama dan unsur-unsurnya terkait pasangan (yaitu, [x_1, x_2, ..., x_m]
dan [y_1, y_2, ..., y_n]
terkait jika dan hanya jika m = n
dan x_1
terkait dengan y_1
dan x_2
terkait dengan y_2
dan seterusnya). Dan bagian yang menyenangkan adalah, dalam kasus kami, karena f
bersifat polimorfik, kita dapat mendefinisikan hubungan apa pun pada elemen daftar!
Mari kita pilih 'a
, 'b
dan lihat f : 'a list -> 'b list
. Sekarang lihat f : 'a list -> bool list
; kami telah menunjukkan bahwa dalam hal ini f
selalu mengembalikan daftar kosong. Kami sekarang mendalilkan bahwa semua elemen 'a
terkait dengan diri mereka sendiri (ingat, kita dapat memilih hubungan apa pun yang kita inginkan), ini menyiratkan bahwa ada zs : 'a list
yang terkait dengan dirinya sendiri. Seperti kita ketahui, f
mengambil nilai terkait dengan yang terkait, ini berarti yang f zs : 'b list
terkait dengan f zs : bool list
, tetapi daftar kedua memiliki panjang sama dengan nol, dan karena yang pertama terkait dengan itu, juga kosong.
Untuk kelengkapan, saya akan menyebutkan bahwa ada bagian tentang dampak rekursi umum (kemungkinan non-terminasi) dalam makalah asli Wadler, dan ada juga makalah yang mengeksplorasi teorema bebas di hadapan seq
.