Учебники

Хаскель — Монады

Монады — это не что иное, как аппликативный функтор с некоторыми дополнительными функциями. Это класс Type, который управляет тремя основными правилами, известными как монадические правила .

Все три правила строго применимы к объявлению Монады, которое выглядит следующим образом:

class Monad m where  
   return :: a -> m a 
   (>>=) :: m a -> (a -> m b) -> m b 
   (>>) :: m a -> m b -> m b 
   x >> y = x >>= \_ -> y 
   fail :: String -> m a  
   fail msg = error msg 

Три основных закона, которые применимы к декларации Монады:

  • Left Identity Law — функция возврата не меняет значение и не должна ничего менять в монаде. Это может быть выражено как «return> => mf = mf».

  • Правильный закон идентификации — функция возврата не меняет значение и не должна ничего менять в монаде. Это может быть выражено как «mf> => return = mf».

  • Ассоциативность — Согласно этому закону, и Functors, и экземпляр Monad должны работать одинаково. Это может быть математически выражено как «(f> ==> g)> => h = f> => (g> = h)».

Left Identity Law — функция возврата не меняет значение и не должна ничего менять в монаде. Это может быть выражено как «return> => mf = mf».

Правильный закон идентификации — функция возврата не меняет значение и не должна ничего менять в монаде. Это может быть выражено как «mf> => return = mf».

Ассоциативность — Согласно этому закону, и Functors, и экземпляр Monad должны работать одинаково. Это может быть математически выражено как «(f> ==> g)> => h = f> => (g> = h)».

Первые два закона повторяют одну и ту же точку, т. Е. Возврат должен иметь одинаковое поведение по обе стороны от оператора связывания .

Мы уже использовали много монад в наших предыдущих примерах, не осознавая, что они монады. Рассмотрим следующий пример, где мы используем монаду списка для генерации определенного списка.

Live Demo

main = do
   print([1..10] >>= (\x -> if odd x then [x*2] else []))

Этот код выдаст следующий вывод —