mtl, transformer, monads-fd, monadLib, dan paradoks pilihan

91

Hackage memiliki beberapa paket untuk trafo monad:

  • mtl : Perpustakaan trafo Monad
  • Transformer : Trafo functor dan monad beton
  • monads-fd : Kelas monad , menggunakan dependensi fungsional
  • monads-tf : Kelas Monad, menggunakan keluarga tipe
  • monadLib : Kumpulan transformator monad.
  • mtl-tf : Pustaka transformator monad menggunakan keluarga tipe.
  • mmtl : Perpustakaan transformator Monad Modular
  • mtlx : Pustaka transformator Monad dengan indeks tipe, menyediakan salinan 'gratis'.
  • compose-trans : Transformator monad yang dapat disusun

(dan mungkin saya melewatkan beberapa)

Yang mana yang akan kami gunakan?

mtl adalah salah satu yang ada di Platform Haskell, tetapi saya terus mendengar di reddit bahwa ini tidak keren.

Tapi apa buruknya pilihan, bukankah itu hanya hal yang baik?

Nah, saya melihat bagaimana misalnya penulis pengakses data harus membuat semua ini untuk memenuhi hanya pilihan yang populer:

  • pustaka data-accessor-monadLib: Fungsi pengakses untuk monad monadLib
  • pustaka data-accessor-monads-fd: Gunakan Accessor untuk mengakses status di kelas monad Status monads-fd
  • pustaka data-accessor-monads-tf: Gunakan Accessor untuk mengakses status di monads-tf State monad type family
  • pustaka data-accessor-mtl: Gunakan Accessor untuk mengakses status di kelas monad mtl State
  • pustaka data-accessor-transformers: Gunakan Accessor untuk mengakses status di monad State transformer

Saya membayangkan bahwa jika ini terus berjalan dan misalnya beberapa paket Arrow yang bersaing berkembang, kita mungkin melihat sesuatu seperti: spoonklink-arrows-transformers, spoonklink-arrows-monadLib, spoonklink-tfArrows-transformers, spoonklink-tfArrows-monadLib, ...

Dan kemudian saya khawatir jika spoonklink bercabang, Hackage akan kehabisan ruang disk. :)

Pertanyaan:

  • Kenapa banyak sekali paket trafo monad?
  • Mengapa mtl [dianggap] tidak keren?
  • Apa perbedaan utamanya?
  • Kebanyakan dari paket yang tampaknya bersaing ini ditulis oleh Andy Gill dan dikelola oleh Ross Paterson. Apakah ini berarti bahwa paket-paket ini tidak bersaing tetapi bekerja bersama dalam beberapa hal? Dan apakah Andy dan Ross menganggap paket mereka sendiri sudah usang?
  • Manakah yang harus Anda dan saya gunakan?
yairchu
sumber
2
Tautan ini membantu saya memahami mtl vs transformers haskell.org/haskellwiki/Monad_Transformer_Library
Brandon Cook
2
Gulir ke bawah untuk komentar @jberryman ! Gunakan mtl atau transfomer, mereka menjadi kompatibel!
Sophie

Jawaban:

70

Beberapa dari mereka hampir sepenuhnya setara:

  • mtlmenggunakan ekstensi GHC, tetapi transformersHaskell 98.
  • monads-fddan monads-tfmerupakan pengaya transformers, masing-masing menggunakan dependensi fungsional dan kelompok tipe, keduanya menyediakan fungsionalitas mtlyang hilang dari transformers.
  • mtl-tfadalah mtlreimplemented menggunakan keluarga jenis.

Jadi intinya, mtl== transformers++ monads-fd, mtl-tf== transformers++ monads-tf. Portabilitas dan modularitas yang ditingkatkan serta transformerspaket-paket terkaitnya adalah mengapa mtltidak keren belakangan ini, menurut saya.

mmtldan mtlxkeduanya tampak mirip dan / atau berdasarkan mtl, dengan perbedaan API dan fitur tambahan.

MonadLibtampaknya memiliki pandangan yang agak berbeda tentang masalah, tetapi saya tidak terbiasa dengannya secara langsung. Juga tampaknya menggunakan banyak ekstensi GHC, lebih dari yang lain.

Sekilas compose-transsepertinya metaprogramming lebih seperti hal untuk membuat trafo monad. Ini diklaim kompatibel dengan Control.Monad.Transyang ... Kurasa maksudnya mtl?

Bagaimanapun, saya menyarankan algoritma keputusan berikut:

  • Apakah Anda memerlukan monad standar untuk proyek baru? Gunakan transformers& co., Bantu kami berbaring mtluntuk beristirahat.
  • Apakah Anda sudah menggunakan mtldalam proyek besar? transformerstidak sepenuhnya kompatibel, tetapi tidak ada yang akan membunuh Anda karena tidak beralih.
  • Apakah salah satu paket lain menyediakan fungsionalitas tidak biasa yang Anda butuhkan? Sebaiknya gunakan saja daripada menggulung sendiri.
  • Masih belum puas? Buang semuanya, unduh category-extras, dan selesaikan semua masalah dunia dengan satu setengah halaman kode generik abstrak yang tidak masuk akal dan tidak masuk akal .
CA McCann
sumber
2
if mtl == transformers ++ monads-fd, tidak bisakah diterapkan dengan cara ini? (sebagai fase untuk menggantinya) yang akan menghilangkan kebutuhan untuk memiliki hal-hal seperti data-accessor-mtl
yairchu
2
@yairchu: Ya, tapi apa yang Anda harapkan dari saya? :) Mempertahankan kompatibilitas ke belakang tidak pernah semudah kelihatannya, dan mengubah pustaka utama membutuhkan waktu, upaya, dan beberapa derajat dukungan komunitas. Situasi trafo monad adalah masalah yang diketahui tetapi menurut saya itu bukan prioritas utama siapa pun.
CA McCann
5
@yairchu: pada dasarnya itulah yang sedang dilakukan. versi utama berikutnya mtl harus berupa rintisan yang mengimpor transformer + monads-fd, dan kompatibilitas dengan versi tersebut akan menjadi faktor penentu. Perpustakaan kemudian akan dapat diperbarui secara individual sehingga mereka kompatibel dengan mtl 1.1 dan 1.2, dan kemudian aplikasi mendapatkan pigeonholed ke versi mana pun yang diinstal atau diperlukan oleh ketergantungan perpustakaan yang paling ketat.
Edward KMETT
2
Milis perpustakaan saat ini sedang mendiskusikan pemindahan MonadIO (dan mungkin MonadTrans dari mtl dan ke basis. Meskipun, telah terputus apakah akan mengekstrak MonadIO atau MonadBase yang lebih umum terlepas dari kenyataan bahwa "MonadBase" membutuhkan MPTC, fundep, dll. .
Edward KMETT
28
Karena saya menemukan posting ini sangat informatif. Saya pikir saya akan memperbarui googler lain: mtl sekarang tergantung pada transformer, monads-fd sekarang menjadi rintisan di sekitar mtl. Jadi gunakan mtl jika Anda membutuhkan barang ekstra yang dimilikinya, atau cukup impor trafo jika memiliki semua yang Anda butuhkan.
jberryman
19

Untuk saat ini? Anda mungkin harus menggunakan mtl. Apa yang terjadi adalah bahwa transformersperpustakaan sedang difaktorkan keluar dari MTL dengan cara yang monads-fddan monads-tfdapat hidup berdampingan dengan damai, tetapi pada akhirnya pemeriksaan itu belum terjadi.

Ketika itu terjadi, Anda akan dapat mengimpor monads-fddan transformersmendapatkan (hampir) antarmuka yang sama, dengan pengecualian bahwa State, dll. Akan menjadi alias untuk StateT.

Jadi saya akan menulis ke mtl, tapi tidak bergantung pada fakta bahwa State, Reader, dll saat ini dataakan diganti dengan types.

MonadLib adalah alternatif lain yang sedang dikerjakan Iavor, yang dapat digunakan dengan aman karena tidak berbagi nama modul dengan yang lain, tetapi memiliki pola penggunaan yang cukup berbeda.

Edward KMETT
sumber
4
Hidup berdampingan dalam pengertian apa? Digunakan oleh paket yang sama? Diimpor ke dalam modul yang sama? Dikombinasikan ke dalam tumpukan trafo yang sama? Menggabungkan fundep dan TF menurut saya sebagai ide yang buruk, secara umum. Bagaimanapun, saya belum banyak menggunakan transformers& co. namun tidak melihat masalah apa pun selain beberapa perbedaan kecil API vs. mtlsaat mengalihkan beberapa kode (cukup sederhana).
CA McCann
4
Masalahnya adalah fakta bahwa Anda hanya dapat memuat satu paket yang menyediakan modul tertentu. Jadi jika Anda menggunakan pustaka yang menggunakan mtl, bahkan secara internal, Anda tidak dapat mengimpor alternatif. Saat ini persentase peretasan yang sehat menggunakan mtl secara internal dalam beberapa cara. Sejumlah orang lebih suka menggunakan keluarga tipe, dan monads-tf memberi mereka itu, tetapi perlu diingat bahwa saat ini, sampai transformer + pemfaktoran ulang monads-fd selesai, kunci ini kode keluar dari penggunaan perpustakaan yang secara transitif membutuhkan MTL . Itu termasuk beberapa item tiket yang cukup besar.
Edward KMETT
1
Menggunakan transformer + monads- (tf | fd) dalam jangka panjang akan menghindari acar itu, tetapi kami belum sampai di sana. Sementara itu, penggunaan yang dominan mendukung mtl. Jalur pemutakhiran tampaknya versi utama berikutnya dari mtl akan didefinisikan ulang sebagai rintisan yang mengimpor monads-fd dan transformer. Hentian versi utama menyediakan cara yang baik untuk menyatakan dalam file kabal Anda bahwa Anda tidak peduli versi mana yang Anda dapatkan (yaitu Anda tidak peduli tentang Status menjadi alias tipe atau tipe data) dan setelah benturan versi utama itu terjadi kemudian Anda tidak perlu peduli jika setiap perpustakaan yang Anda gunakan memiliki bias yang sama.
Edward KMETT
1
Jadi, pada akhirnya pengalaman Anda sejauh ini adalah apa yang dirancang untuk didukung oleh transformer / monads- (tf | fd). Tapi, apa yang disadari setelah mereka ditulis adalah bahwa komunitas itu sangat buruk dalam berpindah perpustakaan, ketika tidak ada alasan kuat untuk melompat dan banyak alasan warisan untuk tetap tinggal. Oleh karena itu, kebutuhan untuk mendefinisikan ulang mtl dan memperjelas jalur peningkatan.
Edward KMETT
Luar biasa, terima kasih atas penjelasan mendetailnya! Jelas, kode yang saya alihkan memiliki sedikit dependensi eksternal - kebanyakan FFI binding, saya kira. Saya juga tidak menyadari bahwa konflik nama modul itu ... invasif, saya kira? Itu memang membuat segalanya canggung. :(
CA McCann
16

Pemfaktoran yang disebutkan Edward Kmett dalam jawabannya selesai pada akhir 2010. Hasil akhirnya adalah monads-fd , dibangun di atas trafo , menjadi versi 2 dari mtl . Sebagai konsekuensi dari mtl yang ada di mana-mana , monads-tf tidak pernah benar-benar populer. Pada awal 2017, mtl dan transformer adalah satu-satunya library trafo monad yang digunakan secara luas.

duplode
sumber