Haskell işlev bileşimi (.) Ve işlev uygulaması ($) deyimleri: doğru kullanım


129

Real World Haskell'i okuyordum ve sona yaklaşıyorum, ancak (.)ve ($)operatörleriyle ilgili bir tarz meselesi beni kandırıyor .

Diğer işlevlerin bileşimi olan bir işlevi yazdığınızda, şöyle yazarsınız:

f = g . h

Ama bu fonksiyonların sonuna bir şey uyguladığınızda, bunu şöyle yazıyorum:

k = a $ b $ c $ value

Ama kitap bunu şöyle yazardı:

k = a . b . c $ value

Şimdi bana göre işlevsel olarak eşdeğer görünüyorlar, benim gözümde de aynı şeyi yapıyorlar. Bununla birlikte, ne kadar çok bakarsam, insanların işlevlerini kitabın yaptığı gibi yazdıklarını görüyorum:(.) önce ve sonra yalnızca ($)partiyi değerlendirmek için bir değer eklemek için kullanın (kimse birçok dolar kompozisyonuyla bunu yapmaz) .

Kitapları tüm ($)sembolleri kullanmaktan çok daha iyi bir şekilde kullanmanın bir nedeni var mı ? Yoksa burada anlamadığım en iyi uygulamalar var mı? Yoksa gereksiz mi ve bunun için hiç endişelenmemeli miyim?


4
İkinci örneğin şu şekilde yapılabilirk = a $ b $ c value
Thomas Eding

1
Evet olabilir, Zifre'nin aşağıda da bahsettiği gibi, ancak hiçbir şeye zarar vermediği ve (ve şimdi sizin) yorumlarınızın mantıklı olmasını sağladığından onu orada bırakmaya karar verdim. Yine de teşekkürler. +1 :)
Robert Massaioli

2
Diğer bir yaygın yaklaşım da a . b $ c value, üçüncü örnek kadar hoşuma gitmeyen, ancak birkaç karakteri kurtarmasıdır.
John L

Yanıtlar:


153

Sanırım buna otoriteden cevap verebilirim.

Kitapları tüm ($) sembollerini kullanmaktan çok daha iyi bir şekilde kullanmanın bir nedeni var mı?

Özel bir nedeni yok. Bryan ve ben ikimiz de hat gürültüsünü azaltmayı tercih ediyoruz..daha sessiz $. Sonuç olarak, kitap f . g . h $ xsözdizimini kullanır .


3
Peki, bundan daha iyi bir cevap umut edemem; yazarlardan birinin kendisinden. :) Ve bu mantıklı, okudukça sayfada daha sessiz görünüyor. Bunu cevap olarak işaretlemek, çünkü soruyu doğrudan cevaplamaktadır. Cevap için teşekkürler; ve aslında kitap.
Robert Massaioli

38
Yazarla aynı fikirde olmamak , ancak bir şeyi kullanmaktan ziyade yaratmanın zihinsel modelinde daha belirgin başka bir neden olduğunu düşünüyorum . Haskell kullanıcıları, bunun yerine yeni bir akıllı yaratım olarak düşünme eğilimindedir . Şimdi, PHP kullanıcısı gibi prefabbed işlev çağrılarının büyük bir sözlüğünü zincirlemek yerine, oluşturdukları anonim de olsa yeni bir işlevi çağırıyorlar. f.g.hf(g(h()))
Evan Carroll

1
Bu ilginç bir ifade: 'hat gürültüsünü azalt' ve 'daha sessiz'. Bu terminolojide programlama dillerini hiç düşünmedim, ama çok mantıklı.
Rabarberski

53

Aslında eşdeğerdirler: $Operatörün aslında hiçbir şey yapmadığını unutmayın. f $ xolarak değerlendirir f x. Bunun amacı $, sabitlik davranışıdır: doğru ilişkisel ve minimum öncelik. Ek $önceliği yerine gruplama için parantezleri kaldırıp kullanarak, kod parçacıkları şu şekilde görünür:

k = a (b (c (value)))

ve

k = (a . b . c) value

.Versiyon yerine versiyonun tercih edilmesinin $sebebi, yukarıda çok parantezli versiyona tercih edilmekle aynı sebeptir: estetik çekicilik.

Yine de, bazıları parantez yerine infix operatörleri kullanmanın, Lisp'e olası herhangi bir benzerlikten kaçınmak için bazı bilinçaltı dürtülerine dayanıp dayanmadığını merak edebilir (sadece şaka mı ... Sanırım?).


38

Eklemek isterim ki f . g $ x, f . ganlamlı bir sözdizimsel birimdir.

Bu arada, içinde f $ g $ x, f $ ganlamlı bir birim değildir. Bir zincir $belki daha zorunludur - ilk sonucunu almak garasında x, daha sonra yapılacak fkendisine, daha sonra yapılacak fookendisine, daha sonra vs.

Bu arada, bir zincir .muhtemelen daha açıklayıcıdır ve bir anlamda veri akışı merkezli bir görüşe daha yakındır - bir dizi işlev oluşturur ve nihayetinde bunları bir şeye uygular.


2
Haskell'i öğreniyorum (anlamlı bir şey kodlamadım) ama $ 'ı bir tür "boru" operatörü olarak düşünmeyi seviyorum. Terminale çok benziyor | boru (veri akışı sağdan sola hariç), ancak uçbirim işlemleri gibi her birim açıkça bağımsızdır.
LostSalad

1
$Operatör benzer şekilde davranmasını görünüyor <|F # operatörü. Aslında ikisinin de aynı şekilde tanımlandığına inanıyorum - F # (<|) a b = a bve Haskell'de a $ b = a b, ki bunlar esasen eşdeğerdir.
Tom Galvin

@Quackmatic Bellek hizmet veriyorsa (<|) b a = a bgibi kullanıldığından F # içinde olduğundan oldukça emin [1; 2; 3; 4; 5] <| List.map ((+) 1).
BalinKingOfMoria Reinstate CMs

@BalinKingOfMoria <|Operatör, değeri fonksiyona iletmek yerine fonksiyona iletir - kod örneğiniz |>bunun yerine operatörle çalışır .
Tom Galvin

@Hayalhanemersin Birden fazla sürüm olduğunun farkında değildim (F #'ı çok kullanmadım).
BalinKingOfMoria Reinstate CMs

18

Benim için cevabın (a) Don'un dediği gibi düzgünlük ; ve (b) Kodu düzenlerken, işlevimin noktasız bir tarzda sonuçlanabileceğini ve sonra tek yapmam gereken $geri dönüp her şeyi değiştirmek yerine sonuncuyu silmek olduğunu anlıyorum . Kesinlikle küçük bir nokta, ama güzel.


Evet, bu şekilde yazmak için iyi bir neden, eğer bir fonksiyon kompozisyonu ile bitirmek istiyorsanız o zaman daha hızlıdır. :) Tuş vuruşlarını kaydetmek için yay, ama daha da önemlisi zamanı. +1
Robert Massaioli

13

Bu haskell-cafe başlığında bu sorunun ilginç bir tartışması var . Görünüşe göre orada sağdan ilişkilendirme olduğunu tutan bir azınlık bakış açısı var $olan "sadece düz yanlış" ve seçme f . g . h $ xüzerine f $ g $ h $ xkonuyu bir kenara itmenin bir yoludur.


Hey, konuyla ilgili koca bir tartışma buldun. Bu harika, şimdi okuyorum. +1
Robert Massaioli

2
Buradaki benzer argümanlar: ghc.haskell.org/trac/haskell-prime/wiki/…
enrique

$!Ayrıca "düz yanlış" doğru çağrışım özelliğine de sahip olduğuna dikkat edin - Neden $! operatör sağ ilişkisel? .
imz - Ivan Zakharyaschev

3

Bu sadece bir tarz meselesi. Ancak kitabın yaptığı yol bana daha mantıklı geliyor. Tüm fonksiyonları oluşturur ve sonra bunu değere uygular.

Yönteminiz tuhaf görünüyor ve sonuncusu $gereksiz.

Ancak, gerçekten önemli değil. Haskell'de, genellikle aynı şeyi yapmanın birçok doğru yolu vardır.


3
Son $ 'ın gereksiz olduğunu fark etmedim ama yapmalıydım. Teşekkürler ve insanların bu yorumun ne anlama geldiğini bilmeleri için orada bırakacağım.
Robert Massaioli

0

Bunun çok eski bir soru olduğunun farkındayım, ancak bunun bahsedilmeyen başka bir nedeni olduğunu düşünüyorum.

Yeni bir puansız fonksiyon bildiriyorsanız, ilettiğiniz f . g . hdeğer otomatik olarak uygulanacaktır. Ancak yazarsan f $ g $ hişe yaramaz.

Yazarın kompozisyon yöntemini tercih etmesinin nedeni, iyi bir fonksiyon geliştirme pratiğine yol açmasıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.