I want to create a FunctionK instance with anonymous function. Here is the minimal example of that:
import cats.~>
given (Option ~> List) = {
case Some(a) => a :: Nil
case None => Nil
}
However, this snippet throws compile error:
Missing parameter type
I could not infer the type of the parameter x$1
in expanded function:
x$1 =>
x$1 match
{
case Some(a) =>
a :: Nil
case None =>
Nil
}
Expected type for the whole anonymous function:
cats.arrow.FunctionK[Option, List]
Is the compiler not smart enough to infer all the types, or am I using anonymous function not the right way?
Compiled with Scala==3.4.0-RC1 and cats.core==2.10.0
Let's analyze it step by step.
FunctionKis actually not a function. In Scala 3-only world it could be defined as:which would make it a polymorphic function type. But it was defined before Scala 3 became a thing and needs to be backward compatible with the old representation, that it:
which was a Scala 2's workaround for not having polymorphic function types.
In situations like:
we are using Single Abstract Method syntax - compiler sees that we are using lambda syntax for something where we could be using
new FunctionLike[Int, String] { ... }but it also sees that thistrait/abstract classhas only 1 abstract method so it can assume that we want to implement the wholetrait/abstract classby implementing this method (and so we can pretend that it's a function).Thing is, SAM seems to be currently implemented only for normal (monomorphic) methods, and when you are using lambdas for polymorphic ones, it will not make the connection:
In your case, you additionally used syntax for monomorphic function type: currently when you need a polymorphic function type you have to write:
[A] => (a: A) => ...- type parameters have to be explicitly defined and explicitly used in one of the arguments.Gaël's answers explains how you can actually implements it.