Home > database >  Polymorphic method works with type lambda, but not with type wildcard in Scala 3
Polymorphic method works with type lambda, but not with type wildcard in Scala 3

Time:11-01

In Scala 3 I can define a functor for state using type lambda:

  given stateFunctor[S]: Functor[[A] =>> State[S, A]] with
    override def map[A, B](a: State[S, A])(fx: A => B): State[S, B] = State(a.run.andThen { case (s, a) => (s, fx(a)) })

I would expect it to work with ? or _ wildcard:

  given stateFunctor[S]: Functor[State[S, ?]] with
    override def map[A, B](a: State[S, A])(fx: A => B): State[S, B] = State(a.run.andThen { case (s, a) => (s, fx(a)) })

but I'm getting the following compilation error:

Type argument domain.State[S, ? <: AnyKind] does not have the same kind as its bound [_$1] given stateFunctor[S]: Functor[State[S, ? <: AnyKind]] with

Why doesn't it work? What am I missing? I thought Scala 3 supports kind-projector syntax for type wildcards.

Scala version: 3.1.3

If you need it, here are State and Functor definitions:

case class State[S, A](run:S => (S, A)):
  def exec(s:S):S = run(s)._1
  def eval(s:S):A = run(s)._2
trait Functor[F[_]]:
  def map[A, B](a: F[A])(fx: A => B): F[B]

CodePudding user response:

? is wrong. ? is for existential type State[S, ?] (in Scala 2 it was State[S, _] aka State[S, A] forSome { type A }), not for type lambda.

_ is for type lambda (in Scala 2 they were emulated ({ type F[A] = State[S, A] })#F). So it should be State[S, _] but this is not implemented yet.

https://docs.scala-lang.org/scala3/reference/changed-features/wildcards.html

The syntax of wildcard arguments in types has changed from _ to ?

We would like to use the underscore syntax _ to stand for an anonymous type parameter, aligning it with its meaning in value parameter lists. So, just as f(_) is a shorthand for the lambda x => f(x), in the future C[_] will be a shorthand for the type lambda [X] =>> C[X].

So far you can write [A] =>> State[S, A] or use kind projector State[S, *]

scalaVersion := "3.2.1"

scalacOptions  = "-Ykind-projector"
  • Related