-
-
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
Follow up to #751 #757
Follow up to #751 #757
Conversation
milessabin
commented
Dec 16, 2015
- Added Reducible instance for OneAnd.
- Added Alternative#compose and MonoidK#compose.
Current coverage is
|
I don't know how to interpret that additional |
extends MonoidK[λ[α => F[G[α]]]] { | ||
|
||
implicit def F: MonoidK[F] | ||
implicit def G: MonoidK[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.
We don't actually use this G
at all. The same is true for the current SemigroupK
- if you drop the SemigroupK[G]
implicit evidence, everything still compiles.
We can freely take a SemigroupK[F]
and turn it into a SemigroupK[λ[α => F[G[α]]]
with no requirements on G
(it can even be a polykinded type like Nothing
or Any
!). I think we should probably drop the requirements on G
. I'm also curious if another name would make more sense, since we aren't actually composing two MonoidK
instances together. However, we are creating a MonoidK
instance for the composite type, so it still may be a reasonable name.
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.
Good point ... I'll remove the constraint.
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.
There is usage of the from MonoidK[F] compose MonoidK[G]
(resp. SemigroupK
) which depends on the constraint generating an implicit argument which which be supplied explicitly. I'll try providing two variants, one with the constraint and one without.
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 understand this comment. I'm saying that I think we should be able to change MonoidK[F] compose MonoidK[G]
to simply MonoidK[F].compose[G]
since the MonoidK[G]
is ignored as far as I can tell. I might be missing something.
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.
What I meant is that there is usage of the form f compose g
for this entire family. I think we should preserve that, and also add an operator of the form f.composedWith[G]
for the cases where the constraint isn't necessary.
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.
Hmm I guess that seems to be a bit misleading to me. You aren't really composing the instances at all. You are just grabbing a type parameter from the second one. My inclination would be to have def compose[G[_]]: Semigroup[...]
on SemigroupK
, def compose[G[_]]: MonoidK[...]
on MonoidK
, def compose[G[_]:Applicative: Applicative[...]
on Applicative
, and def compose[G[_]:Applicative]: Alternative[...]
on Alternative
. To me this seems to be the clearest about what's going on and which constraints are needed.
@non I think you originally added the SemigroupK[G]
requirement to compose
. Was that intentional or an oversight? What are your thoughts?
Edit: for the cases where the evidence isn't required, I'm completely happy with calling these something other than compose
to avoid ambiguity.
I've added the unconstrained variants as |
/** | ||
* Compose two Alternative intsances. | ||
*/ | ||
def compose[G[_]](implicit GG: Alternative[G]): Alternative[λ[α => F[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 the GG
constraint can be relaxed to Applicative
while still returning an Alternative
(also on CompositeAlternative
below).
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.
Agreed ... updated accordingly ...
@ceedubs @non I'd like to move this forward if possible. I think the binary We do need the renamed version with just an explicit type argument and no value argument though, and it should have a name other than |
Bump ... |
👍 from me, generally speaking. I would be fine using a name like |
@non |
Sorry for the delayed response. I've been on vacation. I guess I still find am not convinced of the usefulness of the methods that take an instance but don't actually use it, and I'm concerned that they could result in unexpected behavior if someone is expecting a composition of effects from the two type constructors (and the ScalaDoc for For the versions that take a type argument but no value, would |
@milessabin Now that #772 is merged, can you fix conflicts? |
I added PR milessabin#1 to patch up the merge |
👍 |
actually cody has done a pretty good job of convincing me that although composeWith is useful, compose is not really. |
Just to clarify a couple points:
|
I agree that it makes sense not to include |
I have some general concerns about the way we're using |
It sounds like there is some consensus on this. Miles is currently on holiday, so I'll try to put together a PR that includes these changes along with the discussed updates. |
Per feedback on typelevel#757.