Monad'lar hangi programlama sorunlarını çözüyor? [kapalı]


14

Monadların ne olduğunu, nasıl unitve bindçalıştığını açıklayan pek çok yazı okudum , bazıları doğrudan kategori teorisine daldı (en azından benim için), gözleri kanıyor, bazıları bunu görmezden geliyor ve garip analojilerine dokunuyor burrito, kutular ve ne değil.

Birkaç hafta çalıştıktan ve bir sürü kızarmış nörondan sonra, (sanırım) Monad'ların nasıl çalıştığını anlıyorum. Ancak hâlâ anlayışımdan kaçan bir şey var, birkaç gönderinin gerçekten dokunduğu bir şey var (IO ve eyalet hariç):

NEDEN?

Monadlar neden önemlidir? Neden bu kadar önemli? Çözdükleri problemler neler? Bu problemler sadece Monad'larla çözülebilir mi yoksa başka yollar var mı?


3
Programlar büyük ve karmaşıktır. Onları yapılandırmanın yollarına ihtiyacımız var. Birçok yolu var. Monadlar birdir. Oklar birdir. Functor'lar birdir. Nesneler, Sınıflar, Fonksiyonlar, Yöntemler, Modüller, Özellikler, Karışımlar, Paketler, diğerleri, Özel sorunuzun ne olduğu gerçekten açık değil. Neden programları yapılandırmamız gerektiğini mi soruyorsunuz?
Jörg W Mittag

1
@ JörgWMittag: Programları neden yapılandırmamız gerektiğini sormuyorum. Açıkçası büyük bir problem, çözebileceğiniz ve daha sonra büyük olanın çözümünü elde etmek için birleştirebileceğiniz daha küçük olanlara bölünür. Monad'ların hangi sorunları çözdüğünü soruyorum. Öyle mi? Kod yapılandırılıyor mu? Tüm yaygara bu mu? Örneğin, Haskell'de G / Ç'yi böyle yaparsınız. Orada, monad aslında olmadığı zaman saf bir şey gibi davranan bir oyun gibi davranır. Sorum başlığında, bunu daha net bir şekilde nasıl ifade edeceğimi bilmiyorum.
Dummy Me



1
@RobertHarvey: Eklediğiniz ilk iki bağlantıyı da buldum, ancak bu ve diğer gönderilerin yanıtlarında olduğu gibi, yanıtlar doğrudan Belki, Devlet ve IO monad'larına gidiyor, hızlı bir şekilde örneklere veya koda atlıyor ve "çok var "Monads kullanarak çözülebilecek sorunların Diğer sorunlar nelerdir? Aynı örnekleri tekrarlamak yerine aslında problemlerin kökenine (bunlar ne olursa olsun) gider ve Monad'ların bunları nasıl çözdüğünü ve başka bir şey kullanmak yerine neden en iyi seçim olduğunu açıklayan daha yüksek bir cevap arıyorum. Geri bildiriminiz için çok teşekkürler.
Dummy Me

Yanıtlar:


10

Sen yok ihtiyaç şey çözmek için monads. Sadece belirli şeyleri daha basit hale getiriyorlar. Bir çok insan monadları açıklarken çok soyut ve teorik bir yol izler. Çoğunlukla, monadlar programlamada tekrar tekrar ortaya çıkan bir modeldir. Bu modeli tanıyarak, kodumuzu basitleştirebilir ve belirli işlevleri yeniden uygulamaktan kaçınabiliriz.

Haskell için somut bir bakış açısıyla, monad'ların en göze çarpan şey gösterim yapmaktır . Haskell ve diğer dillerdeki liste kavrayışları da monad'lardan büyük ölçüde yararlanmaktadır. Ayrıca Control.Monad gibi kütüphaneler de oluşturabilirsiniz .

Bunların hepsi kullanışlı basitleştirmeler sağlar ve bir monad için uyguladıktan sonra, otomatik olarak tüm monadlar için alırsınız . İşlevsel programlama için kodun yeniden kullanılmasının diğer paradigmalara göre çok daha kolay olmasının başlıca nedenlerinden biri budur.


2
Aslında haskell monads'ın en göze çarpan şeyin aslında beklediğiniz gibi çalışan IO etkilerine sahip olmanın kolay bir yolu olduğunu söyleyebilirim. Monad'ların bize ne verdiğini merak eden herkes Miranda'yı denemeli diye düşünüyorum . Miranda, Haskell'in değiştirmek için tasarlandığı dildir ve Haskell deneyimi olan herkes için öğrenmesi çok kolay olmalıdır. Temel fark, önemsiz olmayan herhangi bir proje için dili Haskell'den çok daha zor hale getiren monadik IO'ya sahip olmamasıdır.
Jules

Evet, IOHaskell'in en önde gelen monad'ı , ancak bireysel monadların örneklerini listelemiyordum. Etkinleştirdikleri kapsamlı soyutlamaların örneklerini listeliyordum. Örneğin, IO için bir monad kullanmayı düşünen ilk adamın neden genel olarak iyi bir fikir olduğunu düşünmeye çalışıyordum.
Karl Bielefeldt

1
@Jules: Veya Haskell'in tarihine bakın. Monad'lardan önce Haskell tasarımcıları, I / O için temel olarak Lazy Streams ve Continuations'ı denediler ve her ikisinin de kullanımı zordu.
Jörg W Mittag

5

Belirli monad'lara bakarsanız ve hangi sorunları çözdüklerini görürseniz anlamanız daha kolaydır. Örneğin, Haskell'de:

  • IO: IO'nun tip sisteminde temsil edilmesini sağlar, böylece saf fonksiyonları IO gerçekleştiren fonksiyonlardan açıkça ayırabilirsiniz.

  • Liste: Liste kavrayışları ve nodeterministik hesaplamalar yapmanızı sağlar.

  • Belki: Null'lara daha iyi bir alternatif ve C # 'ın null birleştirme operatörü ile karşılaştırılabilir bir şeyi destekleme.

  • Parsec: Ayrıştırıcılar yazmak için uygun bir DSL.

Bu yüzden, tek tek monadların mantığını görmek kolaydır (umarım), çünkü hepsi oldukça faydalıdır. Ancak çözdükleri sorunlar da oldukça farklıdır ve yüzünde zincirleme operasyonlar için bazı mantıklarla ilgili olmadıkları sürece, pek fazla ortak noktaları yoktur. Monadlar faydalıdır, çünkü böyle çeşitli araçlar oluşturmanıza izin verirler.

Yukarıdaki örnekler monad olmadan uygulanabilir mi? Kesinlikle ad-hoc bir şekilde uygulanabilirler, ancak dilde domonadların yerleşik olması, tüm monadlarla çalışan -notation gibi doğrudan dil desteğine izin verir .


2

O kafa karıştırıcı yapar bir şey gibi "popüler" işlevleri olduğunu bindve <*>praxis yönlendirilmiştir. Ancak kavramları anlamak için önce diğer işlevlere bakmak daha kolaydır. Monad'ların öne çıktığı da dikkat çekicidir, çünkü diğer bağlantılı kavramlara kıyasla biraz fazladırlar. Bunun yerine functors ile başlayacağım.

Functors bir işlev sunar (Haskell gösteriminde) fmap :: (Functor f) => (a -> b) -> f a -> f b. Başka bir deyişle f, bir işlevi kaldırabileceğiniz bir bağlamınız vardır. Tahmin edebileceğiniz gibi, neredeyse her şey bir işlevdir. Listeler, Belki, Ya fonksiyonlar, I / O, tuples, ayrıştırıcılar ... Her biri bir değerin görülebileceği bir bağlamı temsil eder. Böylece, hemen hemen her bağlamda çalışan çok yönlü işlevleri fmapveya satır içi varyantını kullanarak yazabilirsiniz <$>.

Bağlamlarla başka ne yapmak istersiniz? İki bağlamı birleştirmek isteyebilirsiniz. Eğer bir genelleme almak isteyebilirsiniz Yani zip :: [a] -> [b] -> [(a,b)]böyle örneğin: pair :: (Monoidal f) => f a -> f b -> f (a,b).

Ancak pratikte daha da yararlı olduğu için Applicative, Haskell kütüphaneleri bunun yerine , ve aynı zamanda , aslında bağlamınızla "değerleri" koyabileceğinizi ekleyen Functorve MonoidalVe de bunların bir kombinasyonunu sunar .Unitunit

Sadece içinde çalıştığınız bağlamla ilgili bu üç şeyi belirterek son derece genel fonksiyonlar yazabilirsiniz.

Monadbunun üzerinde ifade edebileceğiniz başka bir şey. Daha önce bahsetmediğim şey, iki bağlamı birleştirmenin iki yoluna sahip olmanızdır: Sadece paironları değil , aynı zamanda onları da istifleyebilirsiniz, örneğin bir liste listeniz olabilir. G / Ç bağlamında bir örnek, bir dosyadan diğer G / Ç eylemlerini okuyabilen bir G / Ç eylemidir, böylece bir türünüz olur FilePath -> IO (IO a). Yürütülebilir bir işlev elde etmek için bu istiflemeden nasıl kurtulabiliriz IO a? İşte burada Monaddevreye joingiriyor, aynı türden iki yığın bağlamı birleştirmemize izin veriyor. Aynı şey ayrıştırıcılar, belki vb. İçin de geçerlidir ve bindsadece daha pratik bir yöntemdir.join

Bu yüzden monadik bir bağlam sadece dört şey sunmak zorundadır ve G / Ç, ayrıştırıcılar, arızalar vb. İçin geliştirilen neredeyse tüm makinelerle kullanılabilir.


1

Monads, kodu basitleştirmenin yanı sıra saf olmayan çeşitli hesaplamaları ifade etmenizi sağlar

  • durum bilgisi olan hesaplama (monad aracılığıyla durumu alma / ayarlama)
  • G / Ç (günlük kaydı, kullanıcı arayüzü, dosya veya yalnızca bir X listesi oluşturun / tüketin)
  • Ayrıca, "doğrusal olmayan" kontrol akışı (istisnalar, belki vb.)

Ve en önemlisi, saf dil yapılarından ödün vermeden ve bundan daha temiz bir dil elde etmeden


2
Doğru - ama bu sadece monadların ne için kullanıldığının bir parçası. Anlayışları listeleyin veya Maybeharici hiçbir şeyle ilgili değil.
JacquesB

Downvoters bunu neden yaptığını açıklarsa yardımcı olur. Bu cevapta yanlış bir şey görmüyorum.
Jules

@JacquesB, ancak durumsal.
Jules

1
Dünya Türleri, Teklik Türleri, Doğrusal Türler de bunu yapmanıza izin verir.
Jörg W Mittag

@Jules Belirsizliği bozan bir monad olarak durum bilgisi var mı? "Durum bilgisi olan" tanımınızın ne olduğunu açıklar mısınız?
Jack,
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.