Saya benar-benar tertarik untuk mencari tahu di mana perbedaannya, dan lebih umum, untuk mengidentifikasi kasus penggunaan kanonik di mana HList tidak dapat digunakan (atau lebih tepatnya, tidak menghasilkan manfaat apa pun dari daftar biasa).
(Saya sadar bahwa ada 22 (saya percaya) TupleN
di Scala, sedangkan satu hanya membutuhkan HList tunggal, tetapi itu bukan jenis perbedaan konseptual yang saya minati.)
Saya telah menandai beberapa pertanyaan dalam teks di bawah ini. Mungkin sebenarnya tidak perlu untuk menjawab mereka, mereka lebih dimaksudkan untuk menunjukkan hal-hal yang tidak jelas bagi saya, dan untuk membimbing diskusi ke arah tertentu.
Motivasi
Saya baru-baru ini melihat beberapa jawaban di SO di mana orang menyarankan untuk menggunakan HLists (misalnya, seperti yang disediakan oleh Shapeless ), termasuk jawaban yang dihapus untuk pertanyaan ini . Itu memunculkan diskusi ini , yang pada gilirannya memicu pertanyaan ini.
Intro
Sepertinya saya, bahwa daftar hanya berguna ketika Anda tahu jumlah elemen dan tipe tepat mereka secara statis. Jumlahnya sebenarnya tidak penting, tetapi sepertinya tidak mungkin Anda perlu membuat daftar dengan elemen yang bervariasi tetapi jenisnya diketahui secara statis, tetapi Anda tidak tahu jumlahnya secara statis. Pertanyaan 1: Bisakah Anda menulis contoh seperti itu, misalnya, dalam satu lingkaran? Intuisi saya adalah bahwa memiliki daftar statis yang tepat secara statis dengan jumlah elemen arbitrer yang tidak diketahui secara statis (relatif sewenang-wenang terhadap hierarki kelas tertentu) tidak kompatibel.
HList vs. Tuples
Jika ini benar, yaitu, Anda secara statis tahu nomor dan jenis - Pertanyaan 2: mengapa tidak menggunakan n-tuple? Tentu saja, Anda dapat memetakan dan melipat di atas HList dengan mudah (yang juga dapat dilakukan, tetapi tidak dengan agak , dilakukan di atas tuple dengan bantuan productIterator
), tetapi karena jumlah dan jenis elemen diketahui secara statis, Anda mungkin bisa mengakses elemen tuple saja langsung dan melakukan operasi.
Di sisi lain, jika fungsi yang f
Anda petakan pada daftar sangat umum sehingga menerima semua elemen - Pertanyaan 3: mengapa tidak menggunakannya melalui productIterator.map
? Ok, satu perbedaan yang menarik bisa datang dari metode overloading: jika kita memiliki beberapa kelebihan f
, memiliki informasi tipe yang lebih kuat yang disediakan oleh hlist (berbeda dengan productIterator) dapat memungkinkan kompiler memilih yang lebih spesifik f
. Namun, saya tidak yakin apakah itu benar-benar berfungsi di Scala, karena metode dan fungsi tidak sama.
Masukan dan masukan pengguna
Membangun asumsi yang sama, yaitu, bahwa Anda perlu mengetahui jumlah dan jenis elemen secara statis - Pertanyaan 4: dapatkah hlists digunakan dalam situasi di mana elemen bergantung pada jenis interaksi pengguna? Misalnya, bayangkan mengisi daftar dengan elemen di dalam lingkaran; elemen dibaca dari suatu tempat (UI, file config, interaksi aktor, jaringan) hingga kondisi tertentu berlaku. Seperti apa tipe daftar itu? Mirip untuk spesifikasi antarmuka getElements: HList [...] yang seharusnya bekerja dengan daftar yang panjangnya tidak diketahui secara statis, dan yang memungkinkan komponen A dalam sistem untuk mendapatkan daftar elemen arbitrer dari komponen B.
FunctionN
sifat tidak tahu bagaimana mengabstraksikan data: github.com/paulbutcher/ScalaMock/blob/develop/core/src/main/… github.com/paulbutcher/ScalaMock/blob / mengembangkan / core / src / main / ... Sayangnya aku tidak menyadari cara apapun yang dapat saya gunakan tak berbentuk untuk menghindari hal ini, mengingat bahwa saya harus berurusan dengan "nyata"FunctionN
sUntuk lebih jelasnya, HList pada dasarnya tidak lebih dari setumpuk
Tuple2
dengan gula yang sedikit berbeda di atasnya.Jadi pertanyaan Anda pada dasarnya adalah tentang perbedaan antara menggunakan nested tuple vs flat tuple, tetapi keduanya isomorfik sehingga pada akhirnya tidak ada perbedaan kecuali kenyamanan di mana fungsi perpustakaan dapat digunakan dan notasi mana yang dapat digunakan.
sumber
Ada banyak hal yang tidak dapat Anda lakukan dengan tupel:
Anda dapat melakukan semua itu dengan tupel, tetapi tidak dalam kasus umum. Jadi menggunakan HLists membuat kode Anda lebih KERING.
sumber
Saya bisa menjelaskan ini dalam bahasa super sederhana:
Penamaan tuple vs daftar tidak signifikan. HLists bisa disebut sebagai HTuples. Perbedaannya adalah bahwa di Scala + Haskell, Anda dapat melakukan ini dengan tuple (menggunakan sintaks Scala):
untuk mengambil input tuple dari tepat dua elemen dari tipe apa pun, tambahkan elemen ketiga, dan mengembalikan tuple yang diketik sepenuhnya dengan tepat tiga elemen. Tetapi sementara ini benar-benar generik lebih dari jenis, ia harus secara eksplisit menentukan panjang input / output.
Apa yang dapat dilakukan dengan gaya Haskell HList adalah membuat generik ini lebih panjang, sehingga Anda dapat menambahkan ke setiap panjang tuple / daftar dan mendapatkan kembali tuple / daftar yang diketik sepenuhnya secara statis. Manfaat ini juga berlaku untuk koleksi yang diketik secara homogen di mana Anda dapat menambahkan int ke daftar n int yang tepat dan mendapatkan kembali daftar yang diketik secara statis untuk memiliki int yang tepat (n +1) tanpa menetapkan secara eksplisit n.
sumber