0

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?

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
tribbloid
  • 4,026
  • 14
  • 64
  • 103

1 Answers1

3

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

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
  • 2
    In the very first example, `foo(_: C)` works instead of `foo[C]`, but I somehow don't see whether there are shorter ways to eta-expand it. – Andrey Tyukin Feb 09 '23 at 01:02
  • Wow, just wow ... Arrows everywhere – tribbloid Feb 09 '23 at 02:19
  • verified in Scala 3.2.1 ! – tribbloid Feb 09 '23 at 05:20
  • @AndreyTyukin Thanks. Yeah, `foo(_: C)` is a shorthand for `(x: C) => x * 2`. My point was that currently we can't omit `(x: C)` even if there is no value-level parameter in `foo` (for example if `foo` transforms types into values). – Dmytro Mitin Feb 09 '23 at 06:22
  • @AndreyTyukin For example `inline def foo[C <: Int]: C = constValue[C]` or `inline def foo[C <: Int]: C = summonInline[ValueOf[C]].value` – Dmytro Mitin Feb 09 '23 at 06:40