В отличие от функтора, монада может изменять форму?

Мне всегда нравилось следующее интуитивное объяснение мощности монады относительно функтора: монада может изменять форму; функтор не может.

Например: длина $ fmap f [1,2,3] всегда равна 3 .

Однако для монады length $ [1,2,3] >> = g часто не равно 3 . Например, если g определяется как:

g :: (Num a) => a -> [a]
g x = if x==2 then [] else [x]

, то [1,2,3] >> = g равно [1,3] .

Что меня немного беспокоит, так это сигнатура типа g . Кажется невозможным определить функцию, которая изменяет форму ввода, с универсальным монадическим типом, например:

h :: (Monad m, Num a) => a -> m a

Классы типов MonadPlus или MonadZero имеют соответствующие нулевые элементы, которые можно использовать вместо [], но теперь у нас есть кое-что больше, чем монада.

Я прав? Если да, то есть ли способ передать эту тонкость новичку в Haskell. Я хотел бы сделать мою любимую фразу «монады могут менять форму», чуть более честно; если нужно.

19
задан user2023370 10 December 2011 в 14:14
поделиться