Biarkan saya menebus permulaan dari kebingungan ini dengan melempar dengan beberapa disambiguasi. Saya suka menggunakan analogi ke tingkat nilai untuk menjelaskan ini, karena orang cenderung lebih akrab dengannya.
Tipe konstruktor adalah tipe yang bisa Anda terapkan untuk mengetik argumen untuk "membangun" suatu tipe.
Nilai konstruktor adalah nilai yang dapat Anda terapkan ke argumen nilai untuk "membangun" nilai.
Nilai konstruktor biasanya disebut "fungsi" atau "metode". "Konstruktor" ini juga dikatakan "polimorfik" (karena mereka dapat digunakan untuk membangun "barang" dengan "bentuk" yang berbeda), atau "abstraksi" (karena mereka abstrak atas apa yang bervariasi antara instantiasi polimorfik yang berbeda).
Dalam konteks abstraksi / polimorfisme, orde pertama mengacu pada "penggunaan tunggal" abstraksi: Anda mengabstraksi suatu tipe sekali, tetapi tipe itu sendiri tidak dapat mengabstraksi apa pun. Java 5 generics adalah first-order.
Interpretasi tingkat pertama dari karakterisasi abstraksi di atas adalah:
Tipe konstruktor adalah tipe yang dapat Anda terapkan untuk argumen tipe yang tepat untuk "membangun" tipe yang tepat.
Nilai konstruktor adalah nilai yang dapat Anda terapkan ke argumen nilai yang tepat untuk "membangun" nilai yang tepat.
Untuk menekankan tidak ada abstraksi yang terlibat (saya kira Anda bisa menyebutnya "zero-order", tetapi saya belum melihat ini digunakan di mana pun), seperti nilai 1
atau tipe String
, kami biasanya mengatakan sesuatu adalah nilai atau tipe yang "tepat".
Nilai yang tepat adalah "segera dapat digunakan" dalam arti tidak menunggu argumen (tidak abstrak atas mereka). Anggap saja sebagai nilai yang dapat Anda cetak / periksa dengan mudah (membuat serialisasi suatu fungsi curang!).
Tipe yang tepat adalah tipe yang mengklasifikasikan nilai (termasuk konstruktor nilai), konstruktor tipe tidak mengklasifikasikan nilai apa pun (mereka pertama-tama harus diterapkan pada argumen tipe yang tepat untuk menghasilkan tipe yang tepat). Untuk instantiate suatu tipe, perlu (tetapi tidak cukup) bahwa itu adalah tipe yang tepat. (Mungkin kelas abstrak, atau kelas yang Anda tidak memiliki akses.)
"Orde Tinggi" hanyalah istilah umum yang berarti penggunaan berulang polimorfisme / abstraksi. Ini berarti hal yang sama untuk tipe dan nilai polimorfik. Secara konkret, abstraksi tingkat tinggi mengabstraksi sesuatu yang abstrak atas sesuatu. Untuk jenis, istilah "jenis yang lebih tinggi" adalah versi tujuan khusus dari "tingkat tinggi" yang lebih umum.
Dengan demikian, versi tingkat tinggi dari karakterisasi kita menjadi:
Tipe konstruktor adalah tipe yang dapat Anda terapkan untuk mengetik argumen (tipe yang tepat atau tipe konstruktor) untuk "membangun" tipe yang tepat (konstruktor).
Nilai konstruktor adalah nilai yang dapat Anda terapkan ke argumen nilai (nilai yang tepat atau konstruktor nilai) untuk "membangun" nilai yang tepat (konstruktor).
Jadi, "orde yang lebih tinggi" berarti bahwa ketika Anda mengatakan "mengabstraksi lebih dari X", Anda benar-benar bersungguh-sungguh! Yang X
diabstraksi tidak kehilangan "hak abstraksi" sendiri: ia dapat mengabstraksikan semua yang diinginkan. (Omong-omong, saya menggunakan kata kerja "abstrak" di sini untuk berarti: meninggalkan sesuatu yang tidak penting untuk definisi nilai atau tipe, sehingga dapat bervariasi / disediakan oleh pengguna abstraksi sebagai argumen .)
Berikut adalah beberapa contoh (terinspirasi oleh pertanyaan Lutz melalui email) tentang nilai dan jenis yang tepat, tingkat pertama dan tingkat tinggi:
proper first-order higher-order
values 10 (x: Int) => x (f: (Int => Int)) => f(10)
types (classes) String List Functor
types String ({type λ[x] = x})#λ ({type λ[F[x]] = F[String]})#λ
Di mana kelas yang digunakan didefinisikan sebagai:
class String
class List[T]
class Functor[F[_]]
Untuk menghindari tipuan melalui mendefinisikan kelas, Anda perlu entah bagaimana mengekspresikan fungsi tipe anonim, yang tidak dapat diekspresikan secara langsung di Scala, tetapi Anda dapat menggunakan tipe struktural tanpa terlalu banyak biaya sintaksis ( #λ
gaya - style adalah karena https://stackoverflow.com / users / 160378 / retronym afaik):
Di beberapa versi Scala masa depan hipotetis yang mendukung fungsi tipe anonim, Anda bisa mempersingkat baris terakhir dari contoh menjadi:
types (informally) String [x] => x [F[x]] => F[String]) // I repeat, this is not valid Scala, and might never be
(Pada catatan pribadi, saya menyesal pernah berbicara tentang "tipe yang lebih baik", mereka hanya tipe! Ketika Anda benar-benar perlu untuk ambigu, saya sarankan mengatakan hal-hal seperti "ketik parameter konstruktor", "tipe anggota konstruktor" , atau "ketik konstruktor alias", untuk menekankan bahwa Anda tidak berbicara tentang tipe yang tepat saja.)
ps: Untuk memperumit masalah lebih lanjut, "polimorfik" bersifat ambigu dengan cara yang berbeda, karena tipe polimorfik kadang-kadang berarti tipe yang dikuantifikasi secara universal, seperti Forall T, T => T
, yang merupakan tipe yang tepat, karena mengklasifikasikan nilai polimorfik (dalam Scala, nilai ini dapat berupa ditulis sebagai tipe struktural {def apply[T](x: T): T = x}
)