Saya mempelajari Haskell untuk tujuan memahami pemrograman fungsional, dengan harapan bahwa saya akan menerapkan wawasan yang saya peroleh dalam bahasa lain (terutama Groovy, Python, JavaScript.)
Saya memilih Haskell karena saya memiliki kesan bahwa itu sangat fungsional, dan tidak akan membiarkan ketergantungan pada negara.
Saya tidak memilih untuk belajar Haskell karena saya tertarik menavigasi sistem tipe yang sangat kaku.
Pertanyaan saya adalah ini: Apakah sistem tipe yang kuat merupakan produk sampingan yang diperlukan dari bahasa fungsional yang sangat murni, atau apakah ini pilihan desain yang tidak terkait khusus untuk Haskell?
functional-programming
haskell
language-features
type-systems
Eric Wilson
sumber
sumber
Jawaban:
Saya percaya bahwa memahami sistem tipe Haskell adalah penguat untuk memahami pemrograman fungsional.
Hal tentang pemrograman murni fungsional adalah bahwa tanpa adanya efek samping, yang memungkinkan Anda untuk melakukan segala macam hal secara implisit, pemrograman fungsional murni membuat struktur program Anda jauh lebih eksplisit.
Haskell mencegah Anda mendorong benda-benda di bawah karpet, memaksa Anda untuk berurusan dengan struktur program Anda secara eksplisit, dan itu mengajarkan Anda bahasa untuk menggambarkan struktur ini: bahasa tipe. Memahami tipe, terutama tipe kaya seperti Haskell, akan membuat Anda menjadi programmer yang lebih baik dalam bahasa apa pun.
Jika Haskell tidak diketik dengan kuat, konsep seperti monad, fungsi aplikatif dan sejenisnya tidak akan pernah diterapkan pada pemrograman.
sumber
Bahasa fungsional yang paling dinamis diketik adalah Skema. Yang mengatakan, sistem tipe Haskell adalah indikator kemurniannya. Ini pertanyaan "bagaimana seseorang mengukur kemurnian?". Sistem tipe Haskell memungkinkan Anda dengan mudah mencegah tindakan tidak murni
IO
. Untuk melakukan itu, Anda memerlukan sistem tipe statis.Tetapi katakanlah sistem tipe Haskell tidak ada hubungannya dengan pemrograman fungsional. Masih merupakan puncak keangkuhan untuk mengklaim bahwa sistem tipe tidak akan membantu Anda dalam upaya pendidikan ini. Sistem tipe Haskell kaya dan kompleks, dan lebih menarik jika dibandingkan dengan sistem tipe C ++ dan OCaml.
Apakah itu hambatan? Tidak, saya pikir ini adalah aset. Cobalah untuk mempertimbangkan bagaimana menangani kemalasan Haskell tanpa
IO
misalnya.sumber
Clojure diketik secara dinamis, dan hampir semurni Haskell, jadi ada argumen yang bagus bahwa sistem tipe Haskell lebih merupakan pilihan desain daripada persyaratan mutlak. Keduanya pasti memiliki poin kuat, jadi Anda mungkin ingin mempertimbangkan Clojure jika Anda benar-benar tidak menyukai kekakuan Haskell (tetapi lihat di bawah).
Ketika saya pertama kali mulai menggunakan Haskell, saya menganggap sistem tipe itu mengganggu, dan hanya menoleransi karena inferensi tipe. Saya segera menemukan bahwa banyak jenis kesalahan yang dikompilasi oleh kompiler tentang hal-hal yang tidak akan berhasil walaupun jika kompiler membiarkan saya melakukannya (misalnya, secara tidak sengaja menggunakan peta, bukan concatMap). Saya kemudian menemukan bahwa program yang lulus pemeriksaan tipe biasanya benar, atau paling tidak hampir benar. Saya bahkan memiliki fase malas di mana saya melakukan refactoring dengan mengubah jenis fungsi dan membiarkan kompiler memberi tahu saya apa lagi yang perlu diubah. Akhirnya, saya menyadari bahwa sistem tipe Haskell sebenarnya sangat ekspresif dan mulai merancang program saya di sekitar tipe. Itu adalah Cawan Suci Haskell.
sumber
if
s dancond
s dalam Skema, yang saya bayangkan juga dibawa ke Clojure.Sistem tipe Haskell adalah kunci kemampuannya untuk mengisolasi efek dari kode murni. Kecuali jika Anda dapat mengisolasi efek dengan cara lain atau Anda menghilangkan efek seluruhnya, sistem tipe statis yang kuat adalah persyaratan untuk pemrograman fungsional murni.
Haskell adalah contoh bahasa yang sangat bagus dengan sistem tipe statis yang kuat. Jika Anda menginginkan pendidikan yang luas dan menyeluruh dalam ilmu komputer dan desain bahasa pemrograman, Haskell akan menjadi pilihan yang sangat baik sebagai salah satu bahasa yang harus Anda pelajari.
Sistem tipe seharusnya tidak menjadi hambatan besar. Orang yang memprogram cenderung, bahkan ketika menggunakan bahasa yang dinamis, mengikuti konvensi pengetikan yang dapat disandikan menggunakan sistem tipe Haskell. Haskell juga memiliki fitur inferensi tipe yang mengurangi verbositas bila dibandingkan dengan bahasa seperti C ++ dan Java. Ketika Anda mendapatkan pesan kesalahan, kompiler hanya memberi tahu Anda pada waktu kompilasi apa yang akan disampaikan oleh bahasa dengan tipe dinamis saat runtime.
Kebalikan dari sistem tipe dinamis adalah sistem tipe statis, bukan sistem tipe kuat. Sistem tipe yang kuat adalah kebalikan dari sistem tipe yang lemah.
sumber
Ini memberi tahu Anda segera ketika Anda membuat kesalahan bodoh. Ini sangat membantu. Saya telah bekerja di Racket (Skema) musim lalu ini, dan ada beberapa kali saya melewati s-exp yang tidak di-parsing di mana saya mengharapkan parsed ast untuk beberapa fungsi dalam penerjemah saya, dan itu hanya muncul di saya suite tes berukuran sedang. Jika saya memiliki beberapa ketikan statis, itu akan segera menjadi perhatian saya.
Tentu saja, kesalahan logika tidak bisa benar-benar ditangkap oleh sistem tipe, tetapi jumlah cara di mana Anda dapat mengacaukannya sangat berkurang.
Selain itu, ketikkan inferensi memungkinkan Anda mengabaikan sistem jenis jika diinginkan. Masih ada di sana, tetapi tidak memerlukan input aktif dari Anda. Ini masih membantu untuk memahami jenis fungsi Anda, tetapi kode yang benar akan berfungsi dengan baik.
Kemurnian Haskell dikodekan dalam sistem tipenya. IO monad adalah konstruk tingkat tipe yang menghentikan kode tidak murni dari bocor ke fungsi murni, sehingga kemurnian dijamin oleh sistem tipe.
sumber
Menjadi bahasa "fungsional", berarti (terlepas dari hal-hal lain) yang fungsinya adalah objek kelas satu dalam bahasa tersebut.
Menjadi bahasa "murni" berarti bahwa fungsi adalah fungsi matematika (berlawanan dengan prosedur) - diberi input yang sama, mereka selalu menghasilkan output yang sama.
"Bahasa fungsional murni" adalah bahasa yang digunakan oleh keduanya di atas. Saya tidak menyadari dari "-murni ly bahasa fungsional".
Sistem tipe yang kuat adalah salah satu cara yang bersih untuk memiliki bahasa yang murni namun praktis. Jenis membantu kompiler mengetahui optimisasi, selain dari form selanjutnya memastikan kebenaran. (Tapi, itu bukan satu-satunya cara - clojure murni, tetapi tidak memiliki sistem tipe sekuat Haskell.)
Jika sistem tipe mengganggu Anda, saya sarankan Anda untuk mencoba bahasa yang lebih dinamis, seperti Skema, atau berkeliling menggunakan sistem inferensi tipe Haskell.
sumber
Ya, sistem tipe adalah aset yang luar biasa. Akan sangat sulit untuk menggambarkan bagaimana monad bekerja atau bagaimana beberapa kombinator beroperasi tanpa sistem tipe. Pertimbangkan berapa banyak tutorial tentang Haskell yang pertama kali meminta Anda mempertimbangkan jenis fungsi yang dimaksud dengan: t di REPL. Itu tidak tersedia bagi Anda dalam bahasa yang diketik secara dinamis. Tentu, semua kompleksitas dari sistem tipe masih ada. Monad masih monad. Tetapi bahasa tersebut telah memutuskan untuk mencuci tangannya dari masalah ini dan tidak memberikan bantuan sama sekali. Anda sendirian, sobat. Saya tidak mengetuk bahasa yang diketik secara dinamis. Saya sangat mencintai mereka. Skema adalah alat par excellance yang sangat baik. Tetapi Anda akan melihat bahwa ketika kita berbicara tentang hal-hal seperti monad dalam bahasa yang dinamis, kita sering menemukan notasiuntuk menggambarkan jenis prosedur. Seorang programmer fungsional akan bertempur dengan tipe satu atau lain cara. Pemeriksa tipe Haskell hanya memberi Anda alat yang bagus untuk belajar bagaimana melakukan itu.
sumber