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 asf(_)
is a shorthand for the lambdax => f(x)
, in the futureC[_]
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"