SORU
23 Temmuz 2010, Cuma


Nasıl ve neden Haskell monad çalışma Devam ediyor mu?

Bu Devamı olan monad tanımlanır:

newtype Cont r a = Cont { runCont :: (a -> r) -> r }

instance Monad (Cont r) where
    return a = Cont ($ a)
    m >>= k  = Cont $ \c -> runCont m $ \a -> runCont (k a) c

Bu nasıl çalıştığını anlatabilir misin? Ne yapıyor?

CEVAP
23 Temmuz 2010, Cuma


Devam monad hakkında fark ilk şey, temelde, gerçekten değilyapıyorhiç bir şey. Doğru!

Genel olarak devamı temel fikri temsil ediyorbir hesaplama geri kalanı. Böyle bir ifade var ki: foo (bar x y) z. Şimdi, sadece parenthesized bölümü, *4--*özü bubölümtoplam ifadenin, ama sadece geçerli bir fonksiyon değil. Bunun yerine, bir işlevi uygulamak için ihtiyacımız olan bir şeyiçin. Yani, "dinlenme" bar x y tam form yeniden başvurabiliriz \a -> foo a z, Bu durumda. hesaplama konuşabiliriz

Şimdi, "hesaplama geri kalanı düşündüğümüz ifadeyi dışında bir şey olduğu için ama garip bir durum ile çalışmak için" yararlı. bu kavramı olur Yapmak işlerin daha iyi, biz turn şeyler ınside out: özü bu ifadeyi biz eve gidiyoruz, sonra sarın bir işlev alır bir değişkeni temsil gerisini Hesaplaması: \k -> k (bar x y).

Bu Değiştirilmiş Sürümü bize sadece onun içeriğinden bir ifadeyi özü yok, ama bize sağlar esneklik çok verirbu ifadeyi kendi içinde dış bağlam işlemek. Bunun gibi düşünebilirizasma hesaplama gibi bir şeybize sonra ne olacağını açık denetime verilmesi. Şimdi, nasıl böyle bir genelleme yapabilir miyiz? Peki, bu ifadeyi hemen hemen değişmeden, izin ver içeri-dışarı işlevi için parametre yerine, başka bir deyişle bizi \x k -> k x--vermeden, bir şey daha varfonksiyon uygulama, tersine dönmüştür. Kolayca flip ($), yazma veya egzotik yabancı dil bir lezzet biraz daha su ilave edin ve 10 ** bir operatör olarak tanımlayabiliriz.

Şimdi, sıkıcı ve korkunç bir şekilde kafamı allak bullak da olsa, bu form için bir ifade her parçasını çevirmek için basit olurdu. Neyse ki, daha iyi bir yolu var. Düşündüğümüz zaman Haskell programcılar gibibina arka plan çerçevesinde bir hesaplamasanırım bir sonraki şeydiyelim ki, bu bir monad?Ve bu durumda cevapEvetbu , Evet.

Bir monad içine bu açmak için, iki temel yapı taşları ile başlar:

  • Bir monad m yazın değeri için m a monad kapsamında tip a değerine sahip erişimi temsil eder.
  • Bizim çekirdek "askıya hesaplamaları" işlevi uygulama çevrilmiş.

Bu kapsamda 14 ** türü bir şeye erişmek için ne anlama geliyor? Bunun anlamı, bazı değer x :: a, uygulanan ettik flip ($) x vererek bize bir işlev alır bir işlevi alır bir değişken tipi a ve geçerli olan işlevi için x. Hadi cezalı bir hesaplama türü değeri Bool holding. Yazın bu bize ne veriyor?

> :t flip ($) True
flip ($) True :: (Bool -> b) -> b

Asma hesaplamaları için, 22* *yazın biz zaten Cont için imza biliyordu ama şimdi benim için mizah beri belki de bir düş kırıklığı olan (a -> b) -> b... ... çalışır, bu yüzden.

İlginç bir şey için not burada bir tür "ters" için de geçerlidir monad türü: Cont b a temsil eden bir işlev alır bir işlev a -> b değerlendirir b. Devamı niteliğinde olan "gelecek" bir hesaplama, bu yüzden bu tür imza a bir anlamda temsil ediyor "geçmiş".

Yani, ters fonksiyon uygulamanın temel yapı bloğu için monadic türü ne Cont b a ile (a -> b) -> b yerine? a -> (a -> b) -> b a -> Cont b a aynı tür return olarak imza çevirir ve, aslında, tam olarak da bu.

Bundan böyle, her şeyi doğrudan dışarı türlerinden düşüyor: aslında gerçek uygulama ayrıca >>= uygulamak için mantıklı bir yolu Yok. Ama aslında ne olduğunuyapıyor?

Başlangıçta söylediğim şeye geri dönüyoruz bu noktada: devamı monad gerçekten değilyapıyorhiçbir şey. Cont r a basit sadece tür bir şey için eşdeğer bir şey 36**, sadece askıya hesaplama için değişken olarak id sağlayarak. Bu, Cont r a bir monad ama dönüşüm çok basit bir şey, değil 39 ** yalnız gerek olup olmadığını sormak için neden olabilirayrıcabir monad? Tabii ki bu tür Monad bir örnek olarak tanımlamak için yapıcı ama önemsiz bir sarıcı ekliyoruz ki data Id a = Id a gibi olduğundan, işe yaramıyor. Bugerçektenbir monad, kimlik monad yani.

>>= kimlik monad için ne yapar? Yazın imza yine uygulama işlevi basit olan a -> (a -> b) -> b eşdeğer Id a -> (a -> Id b) -> Id b. Cont r a olduğunu tespit ettikten sonra basit bu durumda da rapor eder Id a,, eşdeğerdir(>>=) sadece işlevi uygulamadır.

Elbette, Cont r a bir deli ters dünya herkesin goatees, gerçekte ne olur içerir karıştırma şeyler etrafında kafa karıştırıcı şekillerde sipariş için iki zincir askıya hesaplamaları beraber yeni bir hesaplama askıya alındı, ama özünde, varaslında bir şey alışılmadık değil!Bağımsız fonksiyonları uygulayarak, ho, fonksiyonel bir programcı hayatında başka bir gün hum.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Eddie Bravo

    Eddie Bravo

    17 EKİM 2006
  • Hollyscoop

    Hollyscoop

    30 Ocak 2007
  • LivestrongWoman

    LivestrongWo

    1 Aralık 2011