Kevin Meredith
Kevin Meredith

Reputation: 41909

Understanding Higher Kinded Type Function

Given Parent and Result Algebraic Data Types:

sealed trait Parent
case object Kid extends Parent

sealed trait Result[A <: Parent]
case class ResultImpl[A <: Parent](x: A) extends Result[A]

I then wrote:

def general[A <: Parent, F[_]](x: A, f: A => F[A]): F[A] = 
  f(x)

However, I'm not sure how to call general to get an output of type, ResultImpl[Kid.type].

I attempted:

scala> general(Kid, ResultImpl.apply)
<console>:19: error: inferred kinds of the type arguments (Kid.type,ResultImpl) do not conform to the expected kinds of the type parameters (type A,type F).
ResultImpl's type parameters do not match type F's expected parameters:
type A's bounds <: Parent are stricter than type _'s declared bounds >: Nothing <: Any
       general(Kid, ResultImpl.apply)
       ^
<console>:19: error: type mismatch;
 found   : Kid.type
 required: A
       general(Kid, ResultImpl.apply)
               ^
<console>:19: error: type mismatch;
 found   : Nothing => ResultImpl[Nothing]
 required: A => F[A]
       general(Kid, ResultImpl.apply)
                               ^

How can I do that with the general function?

Upvotes: 1

Views: 88

Answers (1)

Archeg
Archeg

Reputation: 8462

You need to specify that your _ is <: Parent as well, because A is. Also you might want to split arguments into two groups for the compiler to infer A correctly:

def general[A <: Parent, F[_ <: Parent]](x: A)(f: A => F[A]): F[A] =
              f(x)

Then the next works as expected:

general(Kid)(ResultImpl(_))

Upvotes: 4

Related Questions