Apa sajakah teknik yang mungkin saya gunakan untuk secara konsisten refactor kode menghapus ketergantungan pada tipe eksistensial? Biasanya ini digunakan untuk mendiskualifikasi konstruksi yang tidak diinginkan dari jenis Anda serta untuk memungkinkan konsumsi dengan sedikit pengetahuan tentang jenis yang diberikan (atau begitulah pemahaman saya).
Adakah yang datang dengan cara konsisten sederhana untuk menghilangkan ketergantungan pada kode ini yang masih mempertahankan beberapa manfaat? Atau setidaknya ada cara tergelincir dalam abstraksi yang memungkinkan penghapusan tanpa memerlukan kode churn yang signifikan untuk mengatasi perubahan?
Anda dapat membaca lebih lanjut tentang tipe eksistensial di sini ("jika Anda berani ..").
functional-programming
haskell
type-systems
Petr Pudlák
sumber
sumber
Jawaban:
Jenis eksistensial tidak benar-benar dianggap praktik buruk dalam pemrograman fungsional. Saya pikir apa yang membuat Anda tersandung adalah bahwa salah satu kegunaan yang paling sering dikutip untuk eksistensial adalah antipattern typeclass antrian , yang banyak orang percaya adalah praktik buruk.
Pola ini sering digunakan sebagai jawaban atas pertanyaan tentang bagaimana memiliki daftar elemen yang diketik secara heterogen yang semuanya menerapkan typeclass yang sama. Misalnya, Anda mungkin ingin memiliki daftar nilai yang memiliki
Show
instance:Masalah dengan kode seperti ini adalah ini:
AnyShape
adalah untuk mendapatkan wilayahnya.AnyShape
konstruktor untuk memasukkan salah satu tipe bentuk ke dalamAnyShape
tipe tersebut.Jadi ternyata, potongan kode itu tidak benar-benar memberi Anda apa pun yang tidak lebih pendek:
Dalam kasus kelas multi-metode, efek yang sama dapat secara umum dicapai lebih sederhana dengan menggunakan pengkodean "catatan metode" —daripada menggunakan sejenis kelas
Shape
, Anda menentukan jenis rekaman yang bidangnya adalah "metode" dariShape
jenis tersebut. , dan Anda menulis fungsi untuk mengonversi lingkaran dan kotak Anda menjadiShape
s.Tetapi itu tidak berarti bahwa tipe eksistensial adalah masalah! Sebagai contoh, di Rust mereka memiliki fitur yang disebut objek sifat yang sering digambarkan orang sebagai tipe eksistensial atas suatu sifat (versi kelas tipe Rust). Jika typeclasses eksistensial adalah antipattern di Haskell, apakah itu berarti Rust mengambil solusi yang buruk? Tidak! Motivasi di dunia Haskell adalah tentang sintaks dan kenyamanan, bukan tentang prinsip.
Cara yang lebih matematis menempatkan ini menunjukkan bahwa
AnyShape
jenis dari atas danDouble
yang isomorfik -ada adalah "lossless konversi" di antara mereka (baik, menyimpan untuk floating point presisi):Jadi sebenarnya, Anda tidak mendapatkan atau kehilangan kekuatan dengan memilih satu vs yang lain. Yang berarti pilihan harus didasarkan pada faktor-faktor lain seperti kemudahan penggunaan atau kinerja.
Dan perlu diingat bahwa tipe eksistensial memiliki kegunaan lain di luar contoh daftar heterogen ini, jadi ada baiknya memilikinya. Misalnya,
ST
tipe Haskell , yang memungkinkan kita untuk menulis fungsi yang secara eksternal murni tetapi menggunakan operasi mutasi memori secara internal, menggunakan teknik berdasarkan tipe eksistensial untuk menjamin keamanan pada waktu kompilasi.Jadi jawaban umumnya adalah tidak ada jawaban umum. Penggunaan tipe eksistensial hanya dapat dinilai dalam konteks — dan jawabannya mungkin berbeda tergantung pada fitur dan sintaksis apa yang disediakan oleh berbagai bahasa.
sumber
Saya tidak terlalu terbiasa dengan Haskell, jadi saya akan mencoba menjawab bagian umum dari pertanyaan sebagai pengembang C # fungsional non-akademik.
Setelah melakukan beberapa bacaan, ternyata:
Wildcard Java mirip dengan tipe eksistensial:
Perbedaan antara tipe eksistensial Scala dan wildcard Java sebagai contoh
Wildcard tidak diimplementasikan dalam C # sepenuhnya: varians umum didukung, tetapi varians situs panggilan tidak:
C # Generics: Wildcard
Anda mungkin tidak memerlukan fitur ini setiap hari, tetapi ketika Anda melakukannya, Anda akan merasakannya (mis. Harus memperkenalkan jenis tambahan untuk membuat semuanya berfungsi):
Wildcard dalam batasan generik C #
Berdasarkan informasi ini, tipe / wildcard berguna jika diterapkan dengan benar dan tidak ada yang salah dengan itu, tetapi mungkin dapat disalahgunakan seperti fitur bahasa lainnya.
sumber