Различие между типами monadplus, Alternative и Monoid?
стандартная библиотека Haskell typeclasses MonadPlus,Alternative и Monoid каждый предоставляет два метода с практически одинаковой семантикой:
- пустое значение:
mzero,emptyилиmempty. - оператор
a -> a -> aчто объединяет значения в классе вместе:mplus,<|>илиmappend.
все три закона указывают, каких инстанций следует придерживаться:
mempty `mappend` x = x
x `mappend` mempty = x
таким образом, кажется, три классов типов являются обеспечение то же самое методы.
(Alternative предоставляет some и many, но их определения по умолчанию обычно достаточны, и поэтому они не слишком важны с точки зрения этого вопроса.)
Итак, мой вопрос: почему эти три чрезвычайно похожих класса? Есть ли реальная разница между ними, помимо различных ограничений суперкласса?
1 ответ:
MonadPlusиMonoidслужат для разных целей.A
Monoidпараметризуется над типом вида*.class Monoid m where mempty :: m mappend :: m -> m -> mи поэтому он может быть создан практически для любого типа, для которого существует очевидный оператор, который является ассоциативным и который имеет единицу.
,MonadPlusне только указывает, что у вас есть моноидальная структура, но и что эта структура связана с тем, какMonadстроительство, и что эта структура не заботится о значении, содержащемся в монаде, это (частично) указано тем фактом, чтоMonadPlusпринимает аргумент типа* -> *.class Monad m => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m aв дополнение к законам моноидом, у нас есть два потенциальных своды законов мы можем применить к
MonadPlus. К сожалению, община не согласна с тем, какими они должны быть.по крайней мере, мы знаем
mzero >>= k = mzeroно есть еще два конкурирующих расширения, слева (sic) закон распределения
mplus a b >>= k = mplus (a >>= k) (b >>= k)и левый закон улова
mplus (return a) b = return aтак что любой экземпляр
MonadPlusдолжен удовлетворять одному или обоим из этих дополнительных законов.так что насчет
Alternative?
Applicativeбыл определен послеMonad, и логически принадлежит как суперклассMonad, но в основном из-за различных давлений на дизайнеров обратно в Haskell 98, дажеFunctorне был суперклассомMonadдо 2015 года. Теперь мы наконец-то естьApplicativeкак суперклассMonadв GHC (если еще не в языковом стандарте.)эффективно
AlternativeэтоApplicativeчтоMonadPlusэтоMonad.за это мы бы получили
empty <*> m = emptyаналогично тому, что мы имеем с
MonadPlusи существуют аналогичные дистрибутивные и catch свойства, по крайней мере один из которых вы должны удовлетворить.к сожалению, даже
empty <*> m = emptyзакон-это слишком сильное требование. Он не держит для назад, например!когда мы смотрим на MonadPlus, пустой > > = F = пустой закон почти навязан нам. Пустая конструкция не может иметь никаких ' a ' в нем, чтобы вызвать функцию
СfС в любом случае.Applicativeи не суперклассMonadиAlternativeи не суперклассMonadPlus, мы заканчиваем определение обоих экземпляров отдельно.более того, даже если
Applicativeбыл a суперклассMonad, вы бы в конечном итоге нуждаетесь вMonadPlusкласс в любом случае, потому что даже если бы мы подчинилисьempty <*> m = emptyэто не достаточно строго, чтобы доказать, что
empty >>= f = emptyИтак, утверждая, что что-то
MonadPlusсильнее, чем утверждать, что этоAlternative.теперь, по соглашению,
MonadPlusиAlternativeдля данного типа следует согласиться, ноMonoidможет быть полностью разные., например,
MonadPlusиAlternativeнаMaybeсделать очевидную вещь:instance MonadPlus Maybe where mzero = Nothing mplus (Just a) _ = Just a mplus _ mb = mbно
Monoidэкземпляр поднимает полугруппу вMonoid. К сожалению, потому что не былоSemigroupкласс В то время в Haskell 98, он делает это путем запроса aMonoid, но не используя его полностью. ಠ_ಠinstance Monoid a => Monoid (Maybe a) where mempty = Nothing mappend (Just a) (Just b) = Just (mappend a b) mappend Nothing x = x mappend x Nothing = x mappend Nothing Nothing = NothingTL; DR
MonadPlus- это больше, чемAlternative, что в свою очередь является более сильным утверждением, чемMonoid, аMonadPlusиAlternativeэкземпляров типа должно быть связано, тоMonoidможет быть (а иногда и есть) что-то совершенно другое.
Comments