Monada (programowanie)
Monada – w programowaniu funkcyjnym: rodzaj konstruktora abstrakcyjnego typu danych, który implementuje funkcje wiązania (ang. bind) oraz jednostki (ang. unit)[1][2]. Pojęcie to wywodzi się z teorii kategorii, gdzie omawiany abstrakt stanowi monadę nad kategorią typów z funkcjami jako morfizmami. Jednostka określa operację tworzenia singletonu czy też akcji, której wynikiem jest zadana wartość. Wiązanie (w niektórych językach określane jako flat map) buduje na podstawie wyniku poprzedniego obliczenia nowe obliczenie, zachowując przy tym jego formę.
Jedną z głównych cech monad jest to, że pozwalają wynieść pewne mechanizmy i zachowania do abstrakcji, zwalniając tym samym programistę z konieczności ręcznej obsługi kontekstu. Przykładowo, działając na (jakkolwiek zdefiniowanych) zbiorach można opisać jednostkę jako
oraz wiązanie jako
by potem w sposób generyczny budować potoki danych w kompletnym oderwaniu od wewnętrznej implementacji czy nawet interpretacji. Dla przykładu konstruowanie iloczynu kartezjańskiego dwóch zbiorów mogłoby przebiegać tak:
Istotne w tym przykładzie to, że przy definiowaniu operacji prod ani razu nie skorzystano z faktu, że nośnikiem danych jest matematyczny zbiór. Będzie ona zatem działać dla każdej monady, bez względu na jej wewnętrzną reprezentację.
To podejście stanowi popularny wzorzec projektowy, który ma szerokie zastosowanie przy definiowaniu obliczeń zawierających dodatkowe reguły przetwarzające, jak chociażby transformowanie stanu, współbieżność, obsługę wejścia-wyjścia lub wyjątków.
Przykłady
Haskell
W Haskellu monada jest klasą zrzeszającą typy o rodzaju
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
Operacje wiązania >> oraz >>= łączą ze sobą dwie wartości monadyczne, podczas gdy operacja return umieszcza wartość w monadzie. Operator >>= formuje wartość monadyczną obliczającą wynik typu b na podstawie wyniku lewego argumentu będącego wartością monadyczną z wynikiem typu a. Funkcja >> jest używana wtedy, gdy przebieg wiązania nie zależy od wyniku lewego argumentu, a jedynie od jego kontekstu.
Haskell posiada syntaktyczne wsparcie monad przy użyciu tzw. notacji do:
bez_do :: (Monad m, Alternative m) => m Int -> m Int -> m Int
bez_do m1 m2 =
m1 >>= \x1 -> m2 >>= \x2 -> guard (x2 /= 0) >> return (x1 / x2)
z_do :: (Monad m, Alternative m) => m Int -> m Int -> m Int
z_do m1 m2 = do
x1 <- m1
x2 <- m2
guard (x2 /= 0)
return (x1 / x2)
Scala
W Scali monadą jest każda klasa, która implementuje operacje flatMap oraz unit
trait M[A] {
def flatMap[B](f: A => M[B]): M[B]
}
def unit[A](x: A): M[A]
Odpowiednikiem notacji do w Scali jest for comprehensions:
def bez_for(m1 : M[Int], m2 : M[Int]) : M[Int] =
m1.flatMap(x1 => m2.flatMap(x2 => unit[M](x1 + x2)))
def z_for(m1 : M[Int], m2 : M[Int]) : M[Int] =
for {
x1 <- m1
x2 <- m2
} yield (x1 + x2)
Przypisy
- ↑ Haskell Programming From First Principles Christopher Allen, Julie Moronuki, s. 755–799.
- ↑ Demystifying the Monad in Scala [online], Developer News, 4 grudnia 2015 [dostęp 2019-07-20] (ang.).
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.