--- title: Monad localeTitle: монада --- # Законы Монад Существует 3 правила, которые ещё называются законами, которым должны удовлетворять те типы данных, которые хотят быть монадами (на самом деле, это не совсем так, мы можем создать тип, который будет в хаскеле монадой, но не соответствовать законом. Это не запрещено, но очень не приветствуется) ## Левая единица (Left Identity) `return a >>= f` = `f a` Здесь говорится о том, что если мы берём значение и возвращаем его в контексте (заключаем его в монаду), а затем используем `>>=` для передачи его в функцию, то эта операция - то же самое, что и прменение этой функции к исходному значению. ## Правая единица (Right Identity) `m >>= return` = `m` А тут говорится о том, что когда мы используем `>>=` для передачи монадического (заключённого) значения в функцию `return`, мы получаем изначальное монадическое (заключённое) значение. ## Ассоциативность (Associativity) `(m >>= f) >>= g` = `m >>= (\x -> f x >>= g)` Этот закон позволяет нам связывать вызовы монадических функций не смотря на их вложенность. Это может показаться очевидным, и Вы можете подумать, что так и должно быть, но на самом деле ассоциативность обязательна для такого поведения. # Так что на счёт `>>=` и `return`? Всё просто: `>>=`, или 'bind' берёт монаду и функцию, которая принимает на вход чистое значение и возвращает монаду, после этого применяет эту функцию к монаде. Это позволяет нам работать с данными внутри монады, которые не могут быть по-другому доступы другим, немонадическим функциям. `return`, с другой стороны, берёт некое значение и возвращает монаду, содержащую это значение. Наверное, всё, что вы хотели бы знать про `return`, её тип: ```haskell return :: a -> m a ``` # Монада Maybe ```haskell justHead :: Maybe Char justHead = do (x:xs) <- Just "" return x ``` # Монада List возвращает тоже самое значение, что и функция `pure` для класса типов `Applicative` экземпляр Monad \[\], где return x = \[x\] xs >> = f = concat (map f xs) fail \_ = \[\]