类型更高的 lambda

Sim*_*ins 1 types scala dotty polymorphic-functions scala-3

Dotty 中给出以下内容:

object Domain {
  final case class Create(name: String) extends BaseCreate[Create] {
    override type Model = Domain
    override def service[F[_]](client: KeystoneClient[F]): CrudService[F, Domain, Create] = client.domains
  }
}
case class Domain(id: String)

class CrudService[F[_], Model, Create]
final class Domains[F[_]] extends CrudService[F, Domain, Domain.Create]

class KeystoneClient[F[_]] {
  val domains = new Domains[F]
}

trait BaseCreate[Create <: BaseCreate[Create]] {                                                                                                        
  type Model
  def service[F[_]](client: KeystoneClient[F]): CrudService[F, Model, Create]
}
Run Code Online (Sandbox Code Playgroud)

我想“简化” BaseCreate,以便我可以这样实现Create

final case class Create(name: String) extends BaseCreate.Aux[Domain, Create](_.domains)
Run Code Online (Sandbox Code Playgroud)

我试过了:

object BaseCreate {
  abstract class Aux[M, Create](f: [F[_]] =>> KeystoneClient[F] => CrudService[F, M, Create]) extends BaseCreate[Create] {                                        
    type Model = M
    def service[F[_]](client: KeystoneClient[F]): CrudService[F, Model, Create] = f(client)
  }
}
Run Code Online (Sandbox Code Playgroud)

但是编译器抱怨:

Missing type parameter for [F[_$5]] =>> KeystoneClient[F] => CrudService[F, M, Create]
Run Code Online (Sandbox Code Playgroud)

这对我来说没有意义。什么是正确的语法,如果有的话?

使用此代码链接到 scastie

PS:我不想再向BaseCreate. 特别是F因为这意味着该类Domain.Create将需要成为final case class Create[F[_]]根本不是预期的解决方案。

Dmy*_*tin 5

我猜你混淆了类型 lambdas多态函数

类型 lambda 将类型映射到类型,多态函数将值映射到值,只是其参数的类型可以变化。

对于类型 lambda,您应该使用=>>,对于多态函数,您应该使用普通的=>(两次 ie [A] => (a: A) => f(a))。

所以应该是

object BaseCreate {
  abstract class Aux[M, Create](f: [F[_]] => KeystoneClient[F] => CrudService[F, M, Create]) extends BaseCreate[Create] {
    type Model = M
    def service[F[_]](client: KeystoneClient[F]): CrudService[F, Model, Create] = f(client)
  }
}
   
final case class Create(name: String) extends BaseCreate.Aux[Domain, Create](
  [F[_]] => (client: KeystoneClient[F]) => client.domains
)
Run Code Online (Sandbox Code Playgroud)

但它没有在 Dotty 0.28.0-bin-20200920-e99793e-NIGHTLY 中编译并出现错误

object BaseCreate {
  abstract class Aux[M, Create](f: [F[_]] => KeystoneClient[F] => CrudService[F, M, Create]) extends BaseCreate[Create] {
    type Model = M
    def service[F[_]](client: KeystoneClient[F]): CrudService[F, Model, Create] = f(client)
  }
}
   
final case class Create(name: String) extends BaseCreate.Aux[Domain, Create](
  [F[_]] => (client: KeystoneClient[F]) => client.domains
)
Run Code Online (Sandbox Code Playgroud)

似乎是一个错误。