2018-10-12 16:00:59 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								title: Monad
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								localeTitle: монада
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								---
							 
						 
					
						
							
								
									
										
										
										
											2018-10-28 13:48:12 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# Законы Монад
  
						 
					
						
							
								
									
										
										
										
											2018-10-12 16:00:59 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-28 13:48:12 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Существует 3 правила, которые ещё называются законами, которым должны удовлетворять те типы данных, которые хотят быть монадами (на самом деле, это не совсем так, мы можем создать тип, который будет в хаскеле монадой, но не соответствовать законом. Это не запрещено, но очень не приветствуется)
							 
						 
					
						
							
								
									
										
										
										
											2018-10-12 16:00:59 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-28 13:48:12 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								## Левая единица (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
  
						 
					
						
							
								
									
										
										
										
											2018-10-12 16:00:59 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```haskell
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								justHead :: Maybe Char 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 justHead = do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    (x:xs) < -  Just  " "  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return x 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-28 13:48:12 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# Монада List
  
						 
					
						
							
								
									
										
										
										
											2018-10-12 16:00:59 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-28 13:48:12 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								возвращает тоже самое значение, что и функция `pure`  для класса типов `Applicative` 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-12 16:00:59 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								экземпляр Monad \[\], где  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								return x = \[x\]  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								xs >> = f = concat (map f xs)  
							 
						 
					
						
							
								
									
										
										
										
											2018-10-28 13:48:12 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								fail \_ = \[\]