我有这些类型:
SomeTypeClass
一种高级类型,它有一个类型参数 * => * => *
trait SomeTypeClass[P[_, _]] {
def test[F[_], S, T, A, B](f: (A => F[B]) => S => F[T])
(pab: P[A, B])
(implicit ev: Strong[P],
ev2: Choice[P],
ev3: Applicative[F]): P[S, T]
}
Target
它接受三个类型参数:
类型构造函数F[_]
和两个多态类型A, B
case class Target[F[_], A, B](f: A => F[B])
我想实现 Target 的 SomeTypeClass 的一个实例。
我正在使用 kind-projector 插件来创建部分应用的类型。
我想要的方法签名应该是:
implicit def instance: SomeTypeClass[Target[F, *, *]] = new SomeTypeClass[Target[F, *, *]] {
override def test[F[_], S, T, A, B](f: (A => F[B]) => S => F[T])
(pab: Target[F, A, B])
(implicit ev: Strong[Target[F, *, *]],
ev2: Choice[Target[F, *, *]],
ev3: Applicative[F]): Target[F, S, T] = ???
}
我尝试使用两个星形参数使用此语法:
implicit def instance[F[_]]: SomeTypeClass[Target[F, *, *]] = new SomeTypeClass[Target[F, *, *]] {
override def test[F[_], S, T, A, B](f: (A => F[B]) => S => F[T])
(pab: Target[F, A, B])
(implicit ev: Strong[Target[F, *, *]],
ev2: Choice[Target[F, *, *]],
ev3: Applicative[F]): Target[F, S, T] = ???
}
但是F[_]
在实例级别F[_]
声明的会影响在测试方法中声明的(我希望它们是相同的 F),所以我已经转向 λ 语法并得到了两个不同的不需要的结果。
第一个使用λ[(F, A, B) => Target[F, A, B]]
生成的pab
参数,
pab: Target[A, B, B]
而不是pab: Target[F, A, B]
和返回类型Target[S, T, B]
而不是Target[F, S, T]
第二个在三重类型 lambda 参数末尾使用 F (为什么???)
λ[(A, B, F) => Target[F, A, B]]
为参数和返回类型生成了正确pab
的类型,但是对于每个隐式参数,类型Strong[λ[(A, B, F) => Target[F, A, B]]]
而不是
Strong[Target[F, *, *]]]
完整代码:
import cats.Applicative
import cats.arrow.{Choice, Strong}
final case class Target[F[_], A, B](f: A => F[B])
trait SomeTypeClass[P[_, _]] {
def test[F[_], S, T, A, B](f: (A => F[B]) => S => F[T])
(pab: P[A, B])
(implicit ev: Strong[P],
ev2: Choice[P],
ev3: Applicative[F]): P[S, T]
}
object SomeTypeClass {
implicit def instance1: SomeTypeClass[λ[(F, A, B) => Target[F, A, B]]] = new SomeTypeClass[λ[(F, A, B) => Target[F, A, B]]] {
override def test[F[_], S, T, A, B](f: (A => F[B]) => S => F[T])
(pab: Target[A, B, B])
(implicit ev: Strong[Target],
ev2: Choice[Target],
ev3: Applicative[F]): Target[S, T, B] = ???
}
implicit def instance2: SomeTypeClass[λ[(A, B, F) => Target[F, A, B]]] = new SomeTypeClass[λ[(A, B, F) => Target[F, A, B]]] {
override def test[F[_], S, T, A, B](f: (A => F[B]) => S => F[T])
(pab: Target[F, A, B])
(implicit ev: Strong[λ[(A, B, F) => Target[F, A, B]]],
ev2: Choice[λ[(A, B, F) => Target[F, A, B]]],
ev3: Applicative[F]): Target[F, S, T] = ???
}
}
我可以使用这个插件实现所需的语法吗?
为什么插件会为 lambda 类型的“参数”的不同顺序生成不同的类型?