-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add monad.md #332
add monad.md #332
Conversation
implicit def traverseMonadCompose[F[_], G[_]](implicit | ||
FM: Monad[F], | ||
GM: Monad[G], | ||
GT: Traverse[G] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @larsrh tried to prove the monad laws given these constraints and arrived at the conclusion that Traverse is not expressive enough? The types certainly line up though..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was basing this assertion on 12.7.6 of Functional Programming in Scala by Chiusano and Bjarnason, which has this as an exercise.
However, it doesn't address the derivation of the laws, and after searching today I can't find any references to this construction in the literature.
Composing monads (Jones/Duponcheel 1993, http://web.cecs.pdx.edu/~mpj/pubs/RR-1004.pdf) has some information in this direction, though it's not trivial to work out whether the sequence laws laid out in The Essence of the Iterator Pattern (Gibbons/Oliveira 2010, https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf) are sufficient to derive the laws they require on swap.
Should I just drop this section?
For context, here's the scalaz mailing list thread on the subject: |
Cross-posted from Scala-Functional: For a distributive law from one monad to another, you need the lemmas:
and
These both follow from the laws for traversables. [EDIT: does not actually work for non-commutative monads] Pentagon identity: Triangle identity: See here for further reading on distributive laws between monads: |
Well then.. looks like we're good :-) Awesome as usual @runarorama , thanks! |
That's weird, last time I ran ScalaCheck on these constructions gave counterexamples. I'll try to reproduce the problem. |
The first step of the pentagon is unjustified for e.g.
Now It only works for commutative monads. That is |
@woparry first of all, Thanks! |
do we care that the flatten method is actually introduced in the FlatMap type instead of Monad? do we want to make that clear to the reader, or leave that as an implementation detail? |
@woparry can we amend the part in question about an inner traverse that just mentions a caveat with some external links to the relevant discussions? |
Could just say that a distributive law is required, with links to what that means |
I don't think it's worth having those technical details in introductory docs. I've replaced the traverse example in the composition section with a monad transformer example (for Option). |
Looks good to me. Thanks! 👍 |
Request for feedback - is there anything confusing/misleading here that should be corrected before merging? |
} | ||
``` | ||
|
||
This sort of construction is called a monad transformer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I would say this is how we've been approaching monad transformers. In #304, OptionT is its own class that wraps F[Option[A]]
. We don't define a Monad[F[Option[?]]
directly. I think doing so would lead to ambiguity as to whether you were trying to map over F
or the inner option, wouldn't it?
The difference may be subtle, but I'm a bit hesitant to say something in the docs that is different than the actual Cats implementation (though I should note that the referenced pull request is not yet merged).
Current coverage is
|
👍 |
#128