Uygulamalarda saflık ihtiyacı


19

Haskell'in Uygulamalarını öğreniyorum. Görünüşe göre (muhtemelen yanılıyorum) pureişleve gerçekten ihtiyaç duyulmuyor, örneğin:

pure (+) <*> [1,2,3] <*> [3,4,5]

olarak yazılabilir

(+) <$> [1,2,3] <*> [3,4,5]

Birisi pureişlevin açık eşleme üzerinde sağladığı faydaları açıklayabilir fmapmi?


1
Haklısın - pure f <*> xtam olarak aynı fmap f x. İçine puredahil Applicativeolmanın bir nedeni olduğundan eminim, ama neden olduğundan tam olarak emin değilim.
bradrn

4
Bir cevap için zamanım yok ve bunun yine de iyi ya da tam bir sonuç vereceğine ikna olmadım, ama bir gözlem: purebir kişinin Uygulamalı bir hesaplamada "saf" değerleri kullanmasına izin verir. Doğru bir şekilde gözlemlediğiniz pure f <*> xgibi f <$> x, aynısı olsa da, diyelim ki böyle bir eşdeğer yoktur f <*> x <*> pure y <*> z. (En azından ben öyle düşünmüyorum.)
Robin Zigmond

3
Bir başka, daha teorik, gerekçe olarak - onu önemli sınıfla yakından ilişkilendiren alternatif bir formülasyon var - ki bu onun kimlik öğesine karşılık geliyor . (Bu, ilginç olmadan olabileceğini gösteriyor , çünkü - mutlaka bir kimliğe sahip olmadan - hala kullanılıyor. Aslında, şimdi düşünüyorum, PureScript'in tam olarak böyle bir "Uygulamasız " sınıfı olduğunu hatırlıyorum , Ne için kullanıldığını bilmiyorum.)MonoidpureMonoidApplicativepureSemigroupMonoidpure
Robin Zigmond

2
@RobinZigmond fmap (\f' x' z' -> f' x' y z') f <*> x <*> z, sanırım. Fikir, Applicative"değişim" yasası olarak dokümantasyondadır.
HTNW

3
@RobinZigmond Applicativeolmadan pureolarak var Applygelen semigroupoids .
duplode

Yanıtlar:


8

Buradaki yetkinliğimin zirvesindeyim, bu yüzden bunu olduğundan daha fazla almayın, ancak bir yorum için biraz uzun oldu.

pureTür sınıfına dahil etmek için pratik nedenler olabilir , ancak birçok Haskell soyutlaması teorik temellerden kaynaklanmaktadır ve bence bu da geçerlidir Applicative. Belgelerin dediği gibi, güçlü bir gevşek monoidal functor ( ayrıntılandırma için bkz. Https://cstheory.stackexchange.com/q/12412/56098 ). Ben varsayalım pureolarak hizmet vermektedir kimlik tıpkı returniçin yaptığı Monad(bir olan endofunctors kategorisinde monoid ).

Düşünün pureve liftA2:

pure :: a -> f a
liftA2 :: (a -> b -> c) -> f a -> f b -> f c

Biraz şaşıyorsanız liftA2, bunun ikili bir işlem olduğunu hayal edebilirsiniz , bu da belgelerin belirttiği şeydir:

İkili işlevi eylemlere kaldırın.

pure, o zaman, karşılık gelen kimliktir.


6
Kesinlikle. Applicativeolmadan monoidal olan yerine purea, hm, yarıgrupsal functor olmazdı .
leftaroundabout

20

fmapher zaman kesmez. özellikle,pure sen tanıtmak sağlayan şeydir f(burada folduğu Applicativezaten bu yok olduğunda). İyi bir örnek

sequence :: Applicative f => [f a] -> f [a]

Değerleri üreten bir "eylemler" listesi alır ve değerleri bir liste üreten bir eyleme dönüştürür. Listede herhangi bir işlem olmadığında ne olur? Tek aklı başında sonuç, değer üretmeyen bir eylemdir:

sequence [] = pure [] -- no way to express this with an fmap
-- for completeness
sequence ((:) x xs) = (:) <$> x <*> sequence xs

Eğer yapmadıysanız pure, boş bir eylemler listesi istemeniz gerekir. Kesinlikle işe yarayabilir, ancak 0'dan bahsetmeden ekleme veya 1 olmadan çarpma hakkında konuşmak gibi (diğerlerinin söylediği gibi, Applicatives monoidal olduğu için). Kolayca çözülebilecek, pureancak girdilerinizdeki ve diğer bant yardımcılarınızdaki garip kısıtlamalar ile çözülmesi gereken kenar durumlarda tekrar tekrar çalışacaksınız .

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.