---
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 \_ = \[\]
