3

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] 
3
  • 2
    I believe you need a compiler flag. Commented Oct 31, 2022 at 18:30
  • @LuisMiguelMejíaSuárez sorry, witch one are you referring to? I thought -Ykind-projector is used only when using kind-projector (so basically in Scala 2) Commented Oct 31, 2022 at 18:34
  • I've tried adding it using Global / scalacOptions += "-Ykind-projector" in build.sbt, but it didn't work Commented Oct 31, 2022 at 18:37

1 Answer 1

6

? 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" 
Sign up to request clarification or add additional context in comments.

3 Comments

These next few years in Scala are going to be so ugly, when it comes to type projections. The transition plan for what ?, _, and * mean in types is just plain confusing, and until all of the future changes have been implemented fully, it's going to be a mess.
Ahh, you're right! I've read that and missed the part that it's going to be implemented, I thought it's already available. Apparently I cannot read... Thank you, Dmytro!
@SilvioMayolo Not necessarily so big mess if people use Scalafix rules.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.