Search code examples
scalascala-3higher-kinded-typesdottypolymorphic-functions

How to write curried polymorphic function & its higher kind in Scala 3?


In Scala 3, I'm able to write a poly-function of type 1:

  val y = [C <: Int] => (x: C) => x * 2

When I try to generalise it into type 2:

  val z = [C <: Int] => ([D <: Int] => (x: C, y: D) = x * y)

I got the following error:

DependentPoly.scala:19:37: Implementation restriction: polymorphic function literals must have a value parameter

So is this feature not implemented? Or I'm not writing it properly?


Solution

  • Implementation restriction: polymorphic function literals must have a value parameter means that

    val y = [C <: Int] => foo[C]
    

    is illegal (for example for def foo[C <: Int]: C => Int = _ * 2) while

    val y = [C <: Int] => (x: C) => x * 2
    

    is legal.

    Similarly,

    val z = [C <: Int] => [D <: Int] => (x: C, y: D) => x * y
    val z = [C <: Int] => [D <: Int] => (x: C) => (y: D) => x * y
    

    are illegal while

    val z = [C <: Int, D <: Int] => (x: C, y: D) => x * y
    val z = [C <: Int, D <: Int] => (x: C) => (y: D) => x * y
    val z = [C <: Int] => (x: C) => [D <: Int] => (y: D) => x * y
    val z = [C <: Int] => (_: C) => [D <: Int] => (x: C, y: D) => x * y
    val z = [C <: Int] => (_: C) => [D <: Int] => (x: C) => (y: D) => x * y
    

    are legal.

    This is because of

    trait PolyFunction:
      def apply[A](x: A): B[A]
    

    https://docs.scala-lang.org/scala3/reference/new-types/polymorphic-function-types.html

    https://github.com/lampepfl/dotty/pull/4672