TypeScript ile Functor, Applicative Functor ve Monad'ı Anlamak
(evan-moon.github.io)Metin
- Functor'un yalnızca
mapile çözemediği iki problemden (kapsayıcının içindeki fonksiyonun içeride hapsolması sorunu, bileşim sırasında bağlamın iç içe geçmesi sorunu) yola çıkıp applicative functor ve monad'a kadar uzanan süreci TypeScript koduyla açıklıyor - 1988'de Eugenio Moggi'nin programları A → B yerine A → T(B) olarak modellemesinin arka planıyla başlıyor
flatMap = map + joinyapısını ve bunun güvenli kullanımı için üç yasayı (birleşme, sol birim, sağ birim) ele alıyor- Monad'ın neden "endofunctor kategorisindeki monoid nesnesi" olduğunu, tamsayı toplamasındaki monoid ile karşılaştırarak açıklıyor
- Promise'in monadik şekilde çalışsa da neden katı matematiksel anlamda bir monad olmadığından da bahsediyor
Functor'un sınırları: map ile yapılamayanlar
- Curry'lenmiş bir fonksiyon
mapile uygulanırsa sonuçMaybe<(b: number) => number>gibi olur ve fonksiyon kapsayıcının içinde hapsolurmapyalnızca kapsayıcının dışındaki fonksiyonları alabildiği için, içeride hapsolan fonksiyonu başka bir değere uygulamanın yolu yoktur
- Functor döndüren iki fonksiyon bileştirilirse
Maybe<Maybe>gibi bağlam iç içe geçer- Adımlar arttıkça
Maybe<Maybe<Maybe<...>>>şeklinde sonsuz iç içelik oluşur
- Adımlar arttıkça
Applicative functor: kapsayıcının içindeki fonksiyonu uygulamak
applyişlemiyle kapsayıcının içinde hapsolmuş bir fonksiyon, başka bir kapsayıcıdaki değere uygulanabilirapply: T<(A → B)> → T<A> → T<B>
pureişlemiyle saf bir değer kapsayıcıya yerleştirilir- Sınır: hangi kapsayıcıların bileştirileceğinin önceden belirlenmiş olması gerekir
- Önceki hesaplamanın sonucuna bakıp sonraki hesabı belirleyen dinamik sıralı bağımlılık ifade edilemez
Monad: iç içeliği açan işlemin icadı
joinişlemiT<T<A>> → T<A>ile çift kapsayıcıyı tek katmana indirger- JavaScript'teki
Array.prototype.flataynı görevi görür
- JavaScript'teki
- Pratikte
map + joinbirleşimi olanflatMapkullanılırflatMap: T<A> → (A → T<B>) → T<B>mapA → B alırkenflatMapA → T<B> alır ve sonucu tek katmanda tutar
flatMap'in üç yasası
- Birleşme yasası: üçlü iç içe yapı
T(T(T(A)))açılırken içten dışa da açılsa
dıştan içe de açılsa sonucun aynı olması gerekirm.flatMap(f).flatMap(g) === m.flatMap(x => f(x).flatMap(g))
- Sol birim yasası:
pureile koyup hemenflatMapuygulanırsa, bu doğrudan fonksiyonu uygulamakla aynıdırpure(a).flatMap(f) === f(a)
- Sağ birim yasası:
flatMap'epureverilirse orijinal kapsayıcı aynen korunurm.flatMap(pure) === m
"Endofunctor kategorisindeki monoid nesnesi" ifadesinin açılımı
- Programlamadaki functor, tipler dünyasından tipler dünyasına gittiği için bir endofunctor'dur
- Endofunctor'lerin kendilerini nesne olarak alan bir endofunctor kategorisi kurulabilir
- Bunu monoid'in gerekliliklerine (ikili işlem + birleşme yasası + etkisiz eleman) uygularsak:
- ikili işlem =
join - etkisiz eleman =
pure - yapı, tamsayı toplamasındaki monoid ile birebir örtüşür
- ikili işlem =
Promise neden monad değildir
then, dönüş değerine göremapveflatMapişlemlerini karıştırarak işlerPromise<Promise>durumu çalışma zamanında korunmaz, hemen tek katmana indirilir- Pratikte kullanışlı olsa da matematiksel monad yasalarını sağlamaz
2 yorum
Comonad'a da değinir misiniz?
Ah... düşüneceğim hahaha