Saya telah membaca Real World Haskell , dan saya mendekati akhir, tetapi masalah gaya telah mengganggu saya sehubungan dengan (.)
dan ($)
operator.
Ketika Anda menulis fungsi yang merupakan komposisi dari fungsi-fungsi lain, Anda menulisnya seperti:
f = g . h
Tetapi ketika Anda menerapkan sesuatu pada akhir fungsi-fungsi itu, saya menulisnya seperti ini:
k = a $ b $ c $ value
Tetapi buku itu akan menulis seperti ini:
k = a . b . c $ value
Sekarang, bagi saya mereka terlihat setara secara fungsional, mereka melakukan hal yang persis sama di mata saya. Namun, semakin saya melihat, semakin saya melihat orang-orang menulis fungsinya dengan cara yang dilakukan buku itu: menulis dengan yang (.)
pertama dan kemudian hanya pada akhirnya menggunakan ($)
untuk menambahkan nilai untuk mengevaluasi lot (tidak ada yang melakukannya dengan banyak komposisi dolar) .
Apakah ada alasan menggunakan cara buku yang jauh lebih baik daripada menggunakan semua ($)
simbol? Atau ada praktik terbaik di sini yang tidak saya dapatkan? Atau itu berlebihan dan saya tidak perlu khawatir sama sekali?
sumber
k = a $ b $ c value
a . b $ c value
, yang saya tidak suka sebanyak contoh ketiga tetapi menyimpan beberapa karakter.Jawaban:
Saya kira saya bisa menjawab ini dari otoritas.
Tidak ada alasan khusus. Bryan dan saya sama-sama lebih suka mengurangi kebisingan jalur.
.
lebih tenang dari$
. Akibatnya, buku tersebut menggunakanf . g . h $ x
sintaksis.sumber
f.g.h
sebagai kreasi cerdas baruf(g(h()))
. Sekarang mereka memanggil fungsi baru, meskipun anonim, yang mereka buat alih-alih hanya membuat kamus besar panggilan fungsi prefabbed seperti pengguna PHP.Mereka memang setara: Ingat bahwa
$
operator pada dasarnya tidak melakukan apa pun.f $ x
mengevaluasi kef x
. Tujuannya$
adalah perilaku fixity: hak-asosiatif dan prioritas minimal. Menghapus$
dan menggunakan tanda kurung untuk pengelompokan alih-alih prioritas infiks, potongan kode terlihat seperti ini:dan
Alasan untuk lebih memilih
.
versi daripada$
versi adalah alasan yang sama untuk lebih memilih keduanya daripada versi yang sangat kurung di atas: daya tarik estetika.Meskipun, beberapa mungkin bertanya-tanya apakah menggunakan operator infiks bukan tanda kurung didasarkan pada beberapa dorongan bawah sadar untuk menghindari kemungkinan kemiripan dengan Lisp (hanya bercanda ... saya pikir?).
sumber
Saya menambahkan bahwa
f . g $ x
,f . g
adalah unit sintaksis yang bermakna.Sementara itu, di
f $ g $ x
,f $ g
bukan unit yang berarti. Sebuah rantai$
ini bisa dibilang lebih penting - pertama mendapatkan hasilg
darix
, kemudian lakukanf
ke sana, kemudian lakukanfoo
ke sana, kemudian dllSementara itu sebuah rantai
.
bisa dikatakan lebih deklaratif, dan dalam beberapa hal lebih dekat dengan pandangan sentris aliran data - menyusun serangkaian fungsi, dan akhirnya menerapkannya pada sesuatu.sumber
$
Operator tampaknya berperilaku sama dengan<|
operator dalam F #. Saya percaya keduanya didefinisikan sama, pada kenyataannya - di F #,(<|) a b = a b
dan di Haskella $ b = a b
, yang pada dasarnya setara.(<|) b a = a b
di F #, karena ini digunakan seperti[1; 2; 3; 4; 5] <| List.map ((+) 1)
, jika ingatanku.<|
Operator meneruskan nilai ke fungsi, alih-alih meneruskan fungsi ke nilai - contoh kode Anda akan bekerja dengan|>
operator, sebagai gantinya.Bagi saya, saya pikir jawabannya adalah (a) kerapian, seperti kata Don ; dan (b) Saya menemukan bahwa ketika saya mengedit kode, fungsi saya mungkin berakhir dengan gaya point-free, dan yang harus saya lakukan adalah menghapus yang terakhir
$
alih-alih kembali dan mengubah segalanya. Poin kecil, tentu saja, tapi keramahtamahan.sumber
Ada diskusi menarik tentang pertanyaan ini di utas kafe haskell ini . Rupanya ada sudut pandang minoritas yang memegang bahwa associativity tepat
$
adalah "sekadar salah" , dan memilihf . g . h $ x
lebihf $ g $ h $ x
adalah salah satu cara sisi-melangkah masalah ini.sumber
$!
juga memiliki "benar salah" asosiasi kanan - Mengapa $! Operator asosiatif? .Ini hanya masalah gaya. Namun, cara buku itu membuat saya lebih masuk akal. Ini menyusun semua fungsi, dan kemudian menerapkannya pada nilai.
Metode Anda hanya terlihat aneh, dan yang terakhir
$
tidak perlu.Namun, itu tidak masalah. Di Haskell, biasanya ada banyak, banyak, cara yang benar untuk melakukan hal yang sama.
sumber
Saya menyadari ini adalah pertanyaan yang sangat lama, tetapi saya pikir ada alasan lain untuk ini yang belum disebutkan.
Jika Anda mendeklarasikan fungsi bebas titik baru
f . g . h
, nilai yang Anda berikan akan secara otomatis diterapkan. Namun, jika Anda menulisf $ g $ h
, itu tidak akan berhasil.Saya pikir alasan penulis lebih suka metode komposisi adalah karena mengarah pada praktik yang baik untuk membangun fungsi.
sumber