В Хаскелле действуют законы монады?

Из Haskell wiki:

Монады можно рассматривать как стандартный программный интерфейс для различных данных или структур управления, которые захватываются классом Monad. Все общие монады являются его членами:

class Monad m where
  (>>=) :: m a -> (a -> m b) -> m b
  (>>) :: m a -> m b -> m b
  return :: a -> m a
  fail :: String -> m a

В дополнение к реализации функций класса все экземпляры Монада должна подчиняться следующим уравнениям или законам Монады:

return a >>= k  =  k a
m >>= return  =  m
m >>= (\x -> k x >>= h)  =  (m >>= k) >>= h

Вопрос: Являются ли три закона монады внизу фактически принудительно введены языком? Или это дополнительные аксиомы, которые вы должны выполнять, чтобы ваша языковая конструкция "Монады" соответствовала математической концепции "Монады"?

Ответы

Ответ 1

Вы отвечаете за то, что экземпляр Monad подчиняется законам монады. Вот простой пример: не.

Несмотря на то, что его тип совместим с методами Monad, подсчитывая количество использованных операторов привязки, это не Монада, поскольку оно нарушает закон m >>= return = m

{-# Language DeriveFunctor #-}

import Control.Monad

data Count a = Count Int a
    deriving (Functor, Show)

instance Applicative Count where
    pure = return
    (<*>) = ap

instance Monad Count where
    return = Count 0
    (Count c0 a) >>= k = 
        case k a of
            Count c1 b -> Count (c0 + c1 + 1) b

Ответ 2

Нет, законы монады не соблюдаются языком. Но если вы не придерживаетесь их, ваш код может не обязательно вести себя так, как вы ожидали бы в некоторых ситуациях. И это наверняка будет путать пользователей вашего кода.