Skip to content
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 implicit variance support for Profunctor typeclass #3495

Merged

Conversation

gagandeepkalra
Copy link
Contributor

resolves #3452

* scala> val x2: Int => Foo = x1.rightWiden
* }}}
*/
def rightWiden[A, B, BB >: B](fab: F[A, B]): F[A, BB] = fab.asInstanceOf[F[A, BB]]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added these both to avoid lmap and rmap with identity

@@ -23,24 +25,45 @@ class VarianceSuite extends CatsSuite {
}

test("Auto-variance should widen a bifunctor automatically") {
def shouldInfer[F[_, _]: Bifunctor](fi: F[Int, Int]) =
def shouldInfer[F[_, _]: Bifunctor](fi: F[Int, Int]): F[Either[Bar, Baz.type], Either[Bar, Baz.type]] =
Copy link
Contributor Author

@gagandeepkalra gagandeepkalra Jun 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor, thought that the test would be more readable if explicitly typed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to assert here that scalac can infer the correct result type :)

Copy link
Contributor Author

@gagandeepkalra gagandeepkalra Jun 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I think I misunderstood something-

inferred method supposed to return F[Either[Foo, Foo], Either[Foo, Foo]], is still able to return F[Either[Bar, Baz.type], Either[Bar, Baz.type]]; this would have been impossible unless F was declared covariant (given Either is already covariant for both it's type parameters).

And this still compiles for we have implicit autoWidenProfunctor in scope.

please let me know if I should revert

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is still checking that the conversion happens at calls site

def inferred[F[_, _]: Bifunctor](fi: F[Int, Int]): F[Either[Foo, Foo], Either[Foo, Foo]] = shouldInfer[F](fi)

If we remove the import cats.conversions.all._ the compilation fails also in this version, so the test is still valid. I don't have strong preferences about the type annotation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now if I think some more, between the two not having types is still more useful, thanks @LukaJCB

barambani
barambani previously approved these changes Jun 24, 2020
@codecov-commenter
Copy link

Codecov Report

Merging #3495 into master will decrease coverage by 0.00%.
The diff coverage is 80.00%.

@@            Coverage Diff             @@
##           master    #3495      +/-   ##
==========================================
- Coverage   91.77%   91.76%   -0.01%     
==========================================
  Files         383      383              
  Lines        8400     8405       +5     
  Branches      208      219      +11     
==========================================
+ Hits         7709     7713       +4     
- Misses        691      692       +1     


trait VarianceConversions extends VarianceConversionsLowPriority {
implicit def autoWidenBifunctor[F[_, _]: Bifunctor, A, B >: A, C, D >: C](fac: F[A, C]): F[B, D] =
Bifunctor[F].leftWiden(Bifunctor[F].rightFunctor.widen(fac))

implicit def autoWidenProfunctor[F[_, _]: Profunctor, A, B <: A, C, D >: C](fac: F[A, C]): F[B, D] =

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the name of this method should reflect the fact that it does not only widen, but narrow, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea as I understood is that we get the behaviour F[A, C] <: F[B, D] given constraints A >: B and C <: D, the opposite however won't hold with these them.

The same is true for other implicits here, if the return type is A then we can return any instance of A or it's subtypes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the suggestion is just to reflect in the name that this also narrows the left (the A). Something on the line of autoConvertVarianceProfunctor or autoNarrowLeftWidenRightProfunctor. Any other suggestion is good. Also considering that this is and implicit, it will probably never be used directly.

def inferred[F[_, _]: Profunctor](fi: F[Int, Int]): F[Either[Foo, Foo], Either[Foo, Foo]] = shouldInfer[F](fi)
}

test("Auto-variance should left widen a profunctor automatically") {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left-narrow, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like I botched up left and right

fi.bimap(i => if (true) Left(Bar(i)) else Right(Baz), identity)

def inferred[F[_, _]: Bifunctor](fi: F[Int, Int]): F[Either[Foo, Foo], Int] = shouldInfer[F](fi)
}

test("Auto-variance should widen a profunctor automatically") {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right-widen, maybe?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. If we don't want to be specific about the side we could also stay general like

Suggested change
test("Auto-variance should widen a profunctor automatically") {
test("Auto-variance should convert a profunctor's variance automatically") {

Copy link
Contributor

@barambani barambani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@LukaJCB LukaJCB merged commit 32dde51 into typelevel:master Jun 29, 2020
@gagandeepkalra gagandeepkalra deleted the profunctor/addAutoVarianceSupport branch June 30, 2020 01:00
@travisbrown travisbrown added this to the 2.2.0-RC1 milestone Jul 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add implicit variance materialization for profunctor
6 participants