Saya cukup yakin semua orang akrab dengan metode generik formulir:
T DoSomething<T>(T item)
Fungsi ini juga disebut parametrically polymorphic (PP), khususnya peringkat-1 PP.
Katakanlah metode ini dapat direpresentasikan menggunakan objek fungsi dari bentuk:
<T> : T -> T
Artinya, <T>
berarti dibutuhkan satu parameter tipe, dan T -> T
berarti ia mengambil satu parameter tipe T
dan mengembalikan nilai dari tipe yang sama.
Maka yang berikut ini adalah fungsi peringkat-2 PP:
(<T> : T -> T) -> int
Fungsi tidak mengambil parameter tipe itu sendiri, tetapi mengambil fungsi yang mengambil parameter tipe. Anda dapat melanjutkan ini secara iteratif, membuat sarang semakin dalam, semakin dalam, mendapatkan PP dengan peringkat yang lebih tinggi dan lebih tinggi.
Fitur ini sangat jarang di antara bahasa pemrograman. Bahkan Haskell tidak mengizinkannya secara default.
Apakah itu berguna? Bisakah itu menggambarkan perilaku yang sulit untuk dijelaskan sebaliknya?
Juga, apa artinya sesuatu menjadi tidak bijaksana ? (pada konteks ini)
let sdff = (g : (f : <T> (e : T) => void) => void) => {}
Jawaban:
Secara umum, Anda menggunakan polimorfisme tingkat tinggi ketika Anda ingin callee dapat memilih nilai parameter tipe, daripada pemanggil . Sebagai contoh:
Setiap fungsi
g
yang saya lewati untuk inif
harus dapat memberi sayaInt
nilai dari suatu tipe, di mana satu - satunya yangg
tahu tentang tipe itu adalah ia memiliki instanceShow
. Jadi ini halal:Tapi ini bukan:
Salah satu aplikasi yang sangat berguna adalah dalam menggunakan pelingkupan jenis untuk menegakkan pelingkupan nilai . Misalkan kita memiliki objek tipe
Action<T>
, mewakili tindakan yang dapat kita jalankan untuk menghasilkan hasil tipeT
, seperti masa depan atau panggilan balik.Sekarang, anggaplah kita juga memiliki objek
Action
yang dapat mengalokasikanResource<T>
objek:Kami ingin menegakkan bahwa sumber daya itu hanya digunakan di dalam
Action
tempat mereka diciptakan, dan tidak dibagi di antara tindakan yang berbeda atau tindakan yang berbeda dari tindakan yang sama, sehingga tindakan itu deterministik dan berulang.Kita dapat menggunakan tipe dengan peringkat lebih tinggi untuk mencapai hal ini dengan menambahkan parameter
S
keResource
danAction
tipe, yang benar-benar abstrak — itu mewakili “cakupan” dariAction
. Sekarang tanda tangan kami adalah:Sekarang ketika kita memberikan
runAction
sebuahAction<S, T>
, kita yakin bahwa karena “lingkup” parameterS
sepenuhnya polimorfik, itu tidak bisa lepas dari tubuhrunAction
-jadi nilai apapun dari jenis yang menggunakanS
sepertiResource<S, int>
juga tidak dapat melarikan diri!(Dalam Haskell, ini dikenal sebagai
ST
monad, di manarunAction
disebutrunST
,Resource
disebutSTRef
, dannewResource
disebutnewSTRef
.)sumber
ST
monad adalah contoh yang sangat menarik. Bisakah Anda memberikan beberapa contoh kapan polimorfisme tingkat tinggi berguna?data Fetch d = forall a. Fetch (d a) (MVar a)
, yang merupakan sepasang permintaan ke sumber datad
dan slot untuk menyimpan hasilnya. Hasil dan slot harus memiliki jenis yang cocok, tetapi jenis itu tersembunyi, sehingga Anda dapat memiliki daftar permintaan yang heterogen ke sumber data yang sama. Sekarang Anda dapat menggunakan lebih tinggi-peringkat polimorfisme untuk menulis fungsi yang mengambil semua permintaan, mengingat fungsi yang mengambil satu:fetch :: (forall a. d a -> IO a) -> [Fetch d] -> IO ()
.Polimorfisme peringkat tinggi sangat berguna. Dalam Sistem F (bahasa inti dari bahasa FP yang diketik yang Anda kenal), ini penting untuk mengakui "pengkodean Gereja yang diketik" yang sebenarnya adalah cara Sistem F melakukan pemrograman. Tanpa ini, sistem F sama sekali tidak berguna.
Dalam Sistem F, kami mendefinisikan angka sebagai
Penambahan memiliki tipe
yang merupakan tipe peringkat yang lebih tinggi (
forall c.
muncul di dalam panah itu).Ini muncul di tempat lain juga. Misalnya, jika Anda ingin menunjukkan bahwa perhitungan adalah gaya kelanjutan lewat yang tepat (google "codensity haskell") maka Anda akan menganggap ini sebagai
Bahkan berbicara tentang tipe yang tidak berpenghuni dalam Sistem F membutuhkan polimorfisme peringkat yang lebih tinggi
Panjang dan pendek dari ini, menulis fungsi dalam sistem tipe murni (Sistem F, CoC) membutuhkan polimorfisme peringkat yang lebih tinggi jika kita ingin berurusan dengan data yang menarik.
Dalam Sistem F khususnya, pengkodean ini harus "impredikatif". Ini berarti bahwa jumlah semua jenis
forall a.
dikuantifikasi secara absolut . Ini secara kritis termasuk tipe yang kami definisikan. Dalamforall a. a
hala
itu sebenarnya bisa berdiriforall a. a
lagi! Dalam bahasa-bahasa seperti ML, ini bukan masalahnya, mereka dikatakan "predikatif" karena suatu variabel tipe hanya mengukur lebih dari sekumpulan tipe tanpa quantifiers (disebut monotipe). Definisi kita tentangplus
impredicativity diperlukan juga karena kita instantiatedc
dil : Nat
untuk menjadiNat
!Akhirnya, saya ingin menyebutkan satu alasan terakhir di mana Anda ingin impredicativitas dan polimorfisme peringkat tinggi bahkan dalam bahasa dengan tipe rekursif sewenang-wenang (tidak seperti Sistem F). Di Haskell, ada monad untuk efek yang disebut "state thread monad". Idenya adalah bahwa thread negara monad memungkinkan Anda bermutasi tetapi mengharuskan untuk melarikan diri bahwa hasil Anda tidak bergantung pada apa pun yang bisa berubah. Ini berarti bahwa perhitungan ST dapat diamati murni. Untuk menegakkan persyaratan ini kami menggunakan polimorfisme peringkat yang lebih tinggi
Di sini dengan memastikan bahwa
a
itu terikat di luar ruang lingkup di mana kami memperkenalkans
, kami tahu bahwaa
singkatan dari tipe yang dibentuk dengan baik yang tidak bergantungs
. Kami menggunakans
untuk melakukan parameritisasi semua hal yang dapat berubah dalam utas status khusus tersebut sehingga kami tahu bahwa hala
tersebut tidak tergantung pada hal-hal yang dapat berubah dan dengan demikian tidak ada yang lolos dari cakupanST
perhitungan itu! Sebuah contoh yang bagus dari penggunaan tipe untuk menyingkirkan program yang tidak sempurna.Omong-omong, jika Anda tertarik untuk belajar tentang teori jenis, saya sarankan berinvestasi dalam satu atau dua buku yang bagus. Sulit untuk mempelajari hal ini sedikit demi sedikit. Saya menyarankan salah satu buku Pierce atau Harper tentang teori PL secara umum (dan beberapa elemen teori tipe). Buku "Topik lanjutan dalam jenis dan bahasa pemrograman" juga mencakup sejumlah besar teori jenis. Akhirnya "Pemrograman dalam teori tipe Martin Lof" adalah eksposisi yang sangat baik ke dalam teori tipe intensional Martin Lof diuraikan.
sumber