Profesor kami meminta kami untuk memikirkan fungsi dalam OCaml yang memiliki tipe
'a -> 'b
yaitu fungsi dari satu argumen yang bisa berupa apa saja, dan yang dapat mengembalikan apa pun yang berbeda.
Saya berpikir untuk menggunakan raise
fungsi yang mengabaikan argumennya:
let f x = raise Exit
Tetapi profesor mengatakan ada solusi yang tidak memerlukan fungsi apa pun di perpustakaan standar. Saya bingung: bagaimana Anda bisa membuat 'b
jika Anda tidak memilikinya?
Saya bertanya di sini daripada di Stack Overflow karena saya ingin memahami apa yang terjadi, saya tidak ingin hanya melihat program tanpa penjelasan.
programming-languages
typing
functional-programming
Gilles 'SANGAT berhenti menjadi jahat'
sumber
sumber
raise
akan berhasil, jadi kami tahu cara terbaik untuk menjelaskan mengapa solusi yang dicari oleh prof Anda (yang akan bekerja karena alasan yang sama dengan yangraise
berhasil) bekerja.raise : exn -> 'a
jadi saya bisa mendapatkan nilai kembali, saya hanya mengabaikan argumen.Jawaban:
Kerangka itu
let f x = BODY
. Dalam BODY Anda harus menggunakan x-satunya cara generik (misalnya, jangan mengirimkannya ke fungsi yang mengharapkan bilangan bulat), dan Anda harus mengembalikan nilai dari setiap jenis lainnya. Tetapi bagaimana bagian yang terakhir itu benar? Satu-satunya cara untuk memenuhi pernyataan "untuk semua jenis'b
, nilai yang dikembalikan adalah nilai tipe'b
" adalah untuk memastikan fungsi tidak kembali. Sebenarnya ada dua kemungkinan: kesalahan BODY atau tidak berakhir.raise
Kesalahan fungsi , berikut ini tidak berakhir:sumber
Pertama, beberapa komentar. Dengan hanya menggunakan kalkulus lambda yang diketik inti, itu tidak mungkin diperoleh
'a -> 'b
karena sistem pengetikan dalam korespondensi (melalui isomorfisme Curry Howard ) dengan logika intuitionistic, dan formula yang sesuaiA → B
bukanlah tautologi.Ekstensi lain seperti tupel dan pencocokan / kondisional masih mempertahankan beberapa konsistensi logika menambahkan jenis produk
*
yang sesuai dengan ikat logis dan , dan menjumlahkan jenis|
yang sesuai dengan atau . Sekali lagi, jangan berharap mereka menghasilkan'a -> 'b
tipe itu, karena itu akan memungkinkan seseorang untuk membuktikan beberapa formula yang bukan tautologi.Jadi, satu-satunya peluang Anda menggunakan konstruksi lain yang lolos dari logika seperti
raise
(tetapi Anda tidak diizinkan dalam hal ini) ... ataulet rec
! Rekursi memungkinkan untuk membangun program yang tidak pernah berakhir, dan hasilnya dapat diberikan jenis pengembalian sewenang-wenang karena tidak akan pernah diproduksi. Sekarang jika Anda berpikir tentang fungsi non terminating yang paling sepele (yang langsung memanggil dirinya untuk mengembalikan hasil):Anda akan melihat bahwa tipenya persis
'a -> 'b
: apa pun argumen yang diberikan, hasilnya (yang tidak akan pernah dihitung) dapat dianggap memiliki tipe apa pun.Tentu saja ini
f
bukan fungsi yang menarik, tapi itu intinya. Di OCaml, fungsi apa pun yang tipenya tidak terlihat seperti rumus yang valid adalah fungsi yang mencurigakan.sumber
Menggunakan kompiler primitif Anda dapat menulis ini:
(dan memang distribusi kompiler menyediakan ini, meskipun bukan bagian dari bahasa). Ini adalah pemeran identitas yang tidak aman.
Profesor Anda hampir pasti tidak menginginkan ini. Namun, ini juga satu-satunya fungsi yang berguna dengan tipe
'a -> 'b
yang saya ketahui, dan memang digunakan dalam distribusi OCaml itu sendiri.sumber