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

Support lifting polymorphic functions to FunctionK in Scala 3 #3895

Merged
merged 6 commits into from
May 28, 2022

Conversation

bplommer
Copy link
Contributor

No description provided.

@bplommer bplommer marked this pull request as ready for review May 18, 2021 13:46
@bplommer
Copy link
Contributor Author

The CI failure seems to be GH actions playing up.

class FunctionKLiftSuite extends CatsSuite {

test("lift a polymorphic function directly") {
val fHeadOption = FunctionK.lift[List, Option]([X] => (_: List[X]).headOption)
Copy link
Contributor

Choose a reason for hiding this comment

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

Note that in the future the compiler should support polymorphic sam, so you'll be able to write val fHeadOption: List ~> Option = [X] => (_: List[X]).headOption (or maybe even = _.headOption)

* val headOptionK = FunctionK.lift[List, Option]([X] => (_: List[X]).headOption)
* }}}
*/
def lift[F[_], G[_]](f: [X] => F[X] => G[X]): FunctionK[F, G] =
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't a macro is it? Why the name?

I wonder if there could be a Conversion here so you could use a literal in scala 3 without having to call lift.

Copy link
Member

@armanbilge armanbilge May 17, 2022

Choose a reason for hiding this comment

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

I think it's convenient to put it in this file/class, because it was already present (the Scala 2 side uses it for macros). Ideally it could be renamed something more appropriate.

FTR I personally haven't had a good experiencing using Conversion on Scala 3, as it needs a feature import to enable implicit conversions. That makes me tend to stay away.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe I'm wrong but it shouldn't need a feature import if the conversion is on the companion object.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks, I tried slapping an implicit in front of this but actually it doesn't seem to work 🤔

Suggested change
def lift[F[_], G[_]](f: [X] => F[X] => G[X]): FunctionK[F, G] =
implicit def lift[F[_], G[_]](f: [X] => F[X] => G[X]): FunctionK[F, G] =
[error] -- [E007] Type Mismatch Error: /workspace/cats/tests/shared/src/test/scala-3/cats/tests/FunctionKLiftSuite.scala:40:77 
[error] 40 |    val fHeadOption: FunctionK[List, Option] = [X] => (_: List[X]).headOption
[error]    |                                                                             ^
[error]    |    Found:    [X] => (List[X]) => Option[X]
[error]    |    Required: cats.arrow.FunctionK[List, Option]

I also tried using given Conversion[...] but the compiler didn't like that with our current scalacOptions.

Copy link
Member

@armanbilge armanbilge May 19, 2022

Choose a reason for hiding this comment

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

Yeah, it seems this just doesn't work. Maybe worth opening a dotty issue?

//> using scala "3.1.2"
//> using lib "org.typelevel::cats-core::2.7.0"

import cats.arrow.FunctionK

def lift[F[_], G[_]](f: [X] => F[X] => G[X]): FunctionK[F, G] =
  new FunctionK[F, G] {
    def apply[A](fa: F[A]): G[A] = f(fa)
  }

given [F[_], G[_]]: Conversion[[X] => F[X] => G[X], FunctionK[F, G]] = lift(_)

@main def main =
  val fHeadOption: FunctionK[List, Option] = [X] => (_: List[X]).headOption
  val a = List(1, 2, 3)
  assert(fHeadOption(a) == a.headOption)
[error] ./functionk.scala:14:76: Found:    [X] => (List[X]) => Option[X]
[error] Required: cats.arrow.FunctionK[List, Option]
[error]   val fHeadOption: FunctionK[List, Option] = [X] => (_: List[X]).headOption
[error]

Copy link
Member

Choose a reason for hiding this comment

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

I think just type inference fails here:

scala> summon[Conversion[[X] => List[X] => Option[X], FunctionK[List, Option]]](using given_Conversion_X_FunctionK)
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |summon[Conversion[[X] => List[X] => Option[X], FunctionK[List, Option]]](using given_Conversion_X_FunctionK)
  |                                                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |Found:    Conversion[[X] => (Nothing) => Any, FunctionK[F, G]]
  |Required: Conversion[[X] => (List[X]) => Option[X], FunctionK[List, Option]]
  |
  |where:    F is a type variable with constraint <: [_] =>> Any
  |          G is a type variable with constraint <: [_] =>> Any

longer explanation available when compiling with `-explain`
1 error found

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, this seems like maybe it is a bug that could be filed with scala.

Copy link
Member

Choose a reason for hiding this comment

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

I opened scala/scala3#15276.

@armanbilge armanbilge added this to the 2.8.0 milestone May 17, 2022
@armanbilge
Copy link
Member

@bplommer do you mind fixing this up? My efforts to revive it have fallen short.

@armanbilge armanbilge requested a review from johnynek May 23, 2022 21:00
@armanbilge armanbilge merged commit 2d73d64 into typelevel:main May 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants