Iya. Ini disebut "gaya lewat kamus". Kadang-kadang ketika saya melakukan beberapa hal yang sangat rumit, saya perlu membuang typeclass dan mengubahnya menjadi kamus, karena kamus yang lewat lebih kuat 1 , namun seringkali cukup rumit, membuat kode sederhana secara konseptual terlihat cukup rumit. Saya menggunakan gaya passing kamus kadang-kadang dalam bahasa yang bukan Haskell untuk mensimulasikan kacamata ketik (tetapi telah belajar bahwa itu biasanya bukan ide yang bagus seperti kedengarannya).
Tentu saja, setiap kali ada perbedaan dalam kekuatan ekspresif, ada pertukaran. Meskipun Anda dapat menggunakan API yang diberikan dengan lebih banyak cara jika ditulis menggunakan DPS, API mendapatkan lebih banyak informasi jika Anda tidak bisa. Salah satu cara ini muncul dalam praktik adalah dalam Data.Set
, yang bergantung pada kenyataan bahwa hanya ada satu Ord
kamus per jenis. The Set
toko elemen diurutkan sesuai Ord
, dan jika Anda membangun satu set dengan satu kamus, dan kemudian dimasukkan unsur menggunakan satu yang berbeda, seperti akan mungkin dengan DPS, Anda bisa memecahkan Set
's invarian dan menyebabkan kecelakaan. Masalah keunikan ini dapat dikurangi dengan menggunakan hantu eksistensialketik untuk menandai kamus, tetapi, sekali lagi, dengan biaya kompleksitas yang cukup mengganggu di API. Ini juga muncul dengan cara yang hampir sama di Typeable
API.
Bit keunikan tidak sering muncul. Apa jenis kacamata yang hebat adalah menulis kode untuk Anda. Sebagai contoh,
catProcs :: (i -> Maybe String) -> (i -> Maybe String) -> (i -> Maybe String)
catProcs f g = f <> g
yang mengambil dua "prosesor" yang mengambil input dan mungkin memberikan output, dan menggabungkannya, meratakannya Nothing
, harus ditulis dalam DPS kira-kira seperti ini:
catProcs f g = (<>) (funcSemi (maybeSemi listSemi)) f g
Kami pada dasarnya harus mengeja jenis yang kami gunakan lagi, meskipun kami sudah mengeja dalam tanda tangan jenis, dan bahkan itu berlebihan karena kompiler sudah tahu semua jenis. Karena hanya ada satu cara untuk membangun diberikan Semigroup
pada suatu jenis, kompiler dapat melakukannya untuk Anda. Ini memiliki efek tipe "bunga majemuk" ketika Anda mulai mendefinisikan banyak instance parametrik dan menggunakan struktur tipe Anda untuk menghitung untuk Anda, seperti pada Data.Functor.*
kombinator, dan ini digunakan untuk efek yang besar di deriving via
mana Anda pada dasarnya dapat memperoleh semua Struktur aljabar "standar" dari tipe Anda ditulis untuk Anda.
Dan bahkan tidak membuat saya mulai menggunakan MPTC dan fundeps, yang memberi informasi kembali ke pemeriksaan ketik dan inferensi. Saya tidak pernah mencoba mengubah hal seperti itu ke DPS - saya menduga itu akan melibatkan banyak bukti kesetaraan - tetapi dalam hal apa pun saya yakin itu akan menjadi lebih banyak pekerjaan untuk otak saya daripada saya akan merasa nyaman dengan.
-
1 U nless Anda gunakan reflection
dalam hal ini mereka menjadi setara dalam kekuasaan - tetapi reflection
juga dapat menjadi rumit untuk digunakan.