SORU
13 Temmuz 2010, Salı


Nasıl olur &;*> telaffuz lt?Haskell:

Üzgünüm, gerçekten Uygulamalı, typeclass işlevleri nasıl telaffuz edildiğini merak ettim benim matematik bilmiyorum:

(<*>) :: f (a -> b) -> f a -> f b
(*>)  :: f a -> f b -> f b
(<*)  :: f a -> f b -> f a

(Yani, eğer operatörler onlar olmasaydı, ne olabilir?)

Bir yan not olarak, eğer bir şey benim gibi podunks daha dost pure adlandırabilir, buna ne denebilir ki?

CEVAP
14 Temmuz 2010, ÇARŞAMBA


Üzgünüm, gerçekten Uygulamalı, typeclass işlevleri nasıl telaffuz edildiğini merak ettim ben matematik bilmiyorum

Matematik ya da değil, bilmek büyük ölçüde ilgisiz işte, sanırım. Herhalde farkındasınız, Haskell soyut matematik çeşitli alanlarda terminoloji bir kaç bölümü Category Theory, funktorlar ve monadlar biz nereden en önemlisi ödünç alır. Haskell bu ifadeleri kullanırken biraz resmi matematiksel tanımları uzanıyor, ama genellikle iyi açıklayıcı açısından zaten yeterince yakın değiller.

Applicative türü sınıfı bir benzer matematiksel olarak istediği bir yere Functor Monad, arasında oturur. Control.Applicative modül belgeleri ile başlar:

Bu modül yapısı bir functor ve bir monad arasında ara açıklar: saf ifadeler sağlar ve sıralama, ama hiçbir bağlayıcı. (Teknik olarak, güçlü bir gevşek monoidal functor.)

Hmm.

class (Functor f) => StrongLaxMonoidalFunctor f where
    . . .

Monad, bence oldukça gibi çekici değil.

Bu temelde aşağı kaynar ne Applicative özellikle herhangi bir kavram uymuyorilginçmatematiksel olarak, bu yüzden hazır şartlar Haskell kullanılan şekilde yakalayan ortalıkta yok. Yani, bir kenara matematik hemen şimdi.


Eğer (<*>) aramak için ne bilmek istiyorsak temelde ne anlama geldiğini bilmek yardımcı olabilir.

Applicative, Her neyse, neden ve ne içinyapınöyle diyoruz?

Applicative uygulama için ne miktarda kaldırmak için bir yoldurkeyfiFunctor bir işlevleri. Maybe (muhtemelen basit-önemsiz olmayan Functor) ve Bool kombinasyonu (aynı şekilde önemsiz olmayan basit veri türü) düşünün.

maybeNot :: Maybe Bool -> Maybe Bool
maybeNot = fmap not

fmap bizi işlevi Maybe Bool çalışma Bool çalışan not asansör. Ama eğer (&&) asansör istersek ne olacak?

maybeAnd' :: Maybe Bool -> Maybe (Bool -> Bool)
maybeAnd' = fmap (&&)

Peki, istediğimiz bu değilhiç! Aslında, çok fazla işe yaramaz. Zeki olmak için deneyebilirsiniz ve arkadan Maybe içine Bool başka bir... gizlice

maybeAnd'' :: Maybe Bool -> Bool -> Maybe Bool
maybeAnd'' x y = fmap ($ y) (fmap (&&) x)

...ama bu hiç iyi değil. Bir kere yanlış. Başka bir şey için değilçirkin. Denemeye devam edebiliriz, ama var olduğu ortaya çıktıFunctor keyfi bir iş için birden çok bağımsız değişken bir işlev kaldırmak için hiçbir şekilde. Sinir bozucu!

Diğer taraftan, eğer Maybekullansak bunu kolayca yapabiliriz'Monad örnek:

maybeAnd :: Maybe Bool -> Maybe Bool -> Maybe Bool
maybeAnd x y = do x' <- x
                  y' <- y
                  return (x' && y')

Şimdi, o Control.Monad otomatik olarak bunu yapmak için bir işlev sağlar, liftM2 sorunsuz bir çok basit bir işlev--çevirmek için. Onun adı 2 tam olarak iki bağımsız değişken fonksiyonları çalışır bu gerçeği ifade eder; benzer fonksiyonları 3, 4 ve 5 bağımsız değişken fonksiyonları var. Bu işlevleri vardırdaha iyiama mükemmel değil, ve bağımsız değişkenleri çirkin ve beceriksiz olduğunu belirterek.

paper that introduced the Applicative type class bize getiriyor. Bu, yazarlar aslında iki gözlem yapmak:

  • Çok değişken Functor içine fonksiyonları kaldırma yapmak için çok doğal bir şey
  • Bunu yaparken Monad tam yetenekleri gerektirmez

Normal fonksiyon uygulama açısından basit sentezi, Yani "uygulama" gibi basit ve mümkün olduğunca, kağıt tanıtır gibi . doğal kalkması için yazılmıştır ^em>uygulama için gitmemi telkin operatörleri, Functor içine kaldırdıve yazın bir sınıf için gerekli olanı sağlamak için.

Şu noktaya bizi getiriyor:48* *sadece özellik gösterir uygulama. neden boşluk senden daha farklı bir şekilde telaffuz""? yan yana operatör

Ama eğer çok tatmin edici değilse, Control.Monad Bu modül de monadlar için aynı şeyi yapan bir fonksiyon sağlar görüyoruz:

ap :: (Monad m) => m (a -> b) -> m a -> m b

ap elbette, kısa olduğu "" uygulayın. Monad Applicative ve ap herhangi bir özellik ikincisi mevcut alt kümelerini ihtiyacı olduğundan, belki de söyleyebilirizeğer (<*>) bir operatör olmasa, ap çağrılmalıdır.


Diğer taraftan şeyler yaklaşamayız. Functor kaldırma işlemi listeleri map operasyonun bir genelleme çünkü fmap denir. Nasıl bir işlev listeleri (<*>) gibi işe yarar mı? ap elbette listelerinde yok, ne var, ama o kendi başına özellikle yararlı değil.

Aslında, listeler için belki de daha doğal bir yorumu yok. Aşağıdaki tür imza baktığınızda aklınıza ne geliyor?

listApply :: [a -> b] -> [a] -> [b]

Listelere paralel olarak sıraya, ikinci ilgili eleman ilk her fonksiyonu uygulanması fikri hakkında bir şey sadece çok cazip bir teklif var. Ne yazık ki eski dostumuz Monad Bu basit bir işlembu monad yasaları ihlal ediyorlisteler farklı uzunlukta. Ama bir sorun yapar durumda (<*>) bir yol olur Applicative,birlikte fzipWith demeyi hayal edebiliyorum bu yüzden belki de zipWith, genelleştirilmiş bir versiyonu çekimi?


Bu sıkıştırma fikir aslında bize tam daire getiriyor. Böyle şeyleri daha önce monoidal funktorlar matematik hatırlıyor? Adından da anlaşılacağı gibi, bu tür sınıflar Haskell tanıdık hem monoids ve funktorlar, yapısını birleştiren bir yol vardır:

class Functor f where
    fmap :: (a -> b) -> f a -> f b

class Monoid a where
    mempty :: a
    mappend :: a -> a -> a

Bu kutu bir araya koydum ve biraz salladı eğer nasıl olurdu? Functor bir fikri devam edeceğizyapı türü parametre bağımsızve Monoid fonksiyonlarının genel formu devam edeceğiz:

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ?
    mfAppend :: f ? -> f ? -> f ?

İstemiyoruz varsayalım ki bir yol oluşturmak için bir gerçekten "boş" Functor, ve hokkabaz bir değeri rasgele bir tip, yani düzeltme türü mfEmpty f ().

Biz de mfAppend tutarlı bir tür parametresi lazım zorlamak istemiyorum, şimdi bu var:

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ()
    mfAppend :: f a -> f b -> f ?

Sonuç mfAppend türü nedir? Hakkında hiçbir şey bilmediğimiz iki keyfi bir tür var, Birçok seçenek yok. En mantıklı şey sadece tutmak için

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ()
    mfAppend :: f a -> f b -> f (a, b)

Bu noktada mfAppend şimdi açıkça listeleri zip genelleştirilmiş bir şeklidir, ve Applicative kolayca yeniden inşa edebiliriz:

mfPure x = fmap (\() -> x) mfEmpty
mfApply f x = fmap (\(f, x) -> f x) (mfAppend f x)

Bu da bize gösterir ki pure ilgili kimlik öğesi bir Monoid çok iyi isim için olabilir bir şey ima birim değeri, boş bir operasyon ya da böyle.


Uzun, yani özetlemek gerekirse:

  • (<*>) sadece modifiye işlevi bir uygulama olduğunu, ya da okuyabilir "ap" veya "Uygula" ya elide tamamen normal uygulama. işlevi böyle gibi
  • (<*>) da okuyabilirsin yani kabaca listeleri zipWith yaygınlaştırır, "zip funktor", benzer şekilde fmap olarak okuma "ile bir functor göster". gibi

İlk adını tavsiye ediyorum, nedir yani ... anlaşılacağı gibi Applicative türü sınıf--amacına daha yakın.

Aslında, teşvik ediyorumliberal kullanın ve non-telaffuz, tüm kaldırdı uygulama operatörleri:

  • Bir tek bağımsız değişken bir işlev asansörleri (<$>), Functor
  • Bir çok argüman zincirleri (<*>), Applicative bir işlev
  • Varolan bir hesaplama üzerine Monad girdiği bir fonksiyonu olarak bağlar (=<<),

Üç, kalp, normal işlevi, uygulama, biraz baharatlı.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • cyriak

    cyriak

    29 Mart 2006
  • MuscleProdigyTV

    MuscleProdig

    8 Ocak 2011
  • ODN

    ODN

    26 Kasım 2006