How exactly does the `(<*>) = ap` Applicative/Monad law relate the two classes?

岁酱吖の 提交于 2019-12-01 19:20:32

Every Monad gives rise to an Applicative, and for that induced Applicative, <*> = ap will hold definitionally. But given two structures - Monad m and Applicative m - there is no guarantee that these structures agree without the two laws <*> = ap and pure = return. For example, take the 'regular' Monad instance for lists, and the zip-list Applicative instance. While there is nothing fundamentally 'wrong' about a Monad and Applicative instance disagreeing, it would probably be confusing to most users, and so it's prohibited by the Monad laws.

tl;dr The laws in question serve to ensure that Monad and Applicative agree in an intuitively obvious way.

So I assume the ap in the (<*>) = ap law is shorthand for "right-hand side of ap" and the law actually expresses a relationship between >>=, return and <*> right?

It seems to me (<*>) = ap doesn't strictly imply anything (at least post-AMP). Presumably it's trying to express some relationship between <*> and the right-hand side of ap. Maybe I'm being pedantic.

Speaking pedantically, I'd say the opposite: because ap is definitionally equal to its right-hand side, saying (<*>) = ap is exactly the same as saying m1 <*> m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }. It's just the normal first step of dealing with equalities like that: expanding the definitions.

Reply to the comment:

Right, but the definition is free to change.

Then the law would change or be removed too. Just as when/if join is added to Monad the current definition will become a law instead.

it wouldn't have been possible to define it literally as ap = <*>

Do you mean it would be impossible to define ap or the law in this way?

If ap, then you are correct: it would have the wrong type. But stating the law like this would be fine.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!