freeCodeCamp/guide/russian/haskell/monad/index.md

3.2 KiB
Raw Blame History

title localeTitle
Monad монада

Законы Монад

Существует 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, её тип:

return :: a -> m a

Монада Maybe

justHead :: Maybe Char 
 justHead = do 
    (x:xs) <- Just "" 
    return x 

Монада List

возвращает тоже самое значение, что и функция pure для класса типов Applicative

экземпляр Monad [], где
return x = [x]
xs >> = f = concat (map f xs)
fail _ = []