微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

输入更高种类的lambda

如何解决输入更高种类的lambda

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.Create]

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

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

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

final case class Create(name: String) extends BaseCreate.Aux[Domain,Create](_.domains)

我尝试过:

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,Create] = f(client)
  }
}

但是编译器抱怨:

Missing type parameter for [F[_$5]] =>> KeystoneClient[F] => CrudService[F,Create]

这对我没有意义。什么是正确的语法(如果有)?

Link to scastie with this code

PS:我不想在BaseCreate中引入更多类型参数。尤其是F,因为那将意味着类Domain.Create将需要为final case class Create[F[_]],而这根本不是预期的解决方案。

解决方法

我想您将type lambdaspolymorphic functions混淆了。

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

对于lambda类型,应使用=>>,对于多态函数,应使用普通的=>(两次,即[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
)

但是它无法在Dotty 0.28.0-bin-20200920-e99793e-NIGHTLY中编译,但出现错误

Found:    Object with PolyFunction {...}
Required: PolyFunction{
  apply: 
    [F[_$6]]
      (x$1: App.KeystoneClient[F]): 
        App.CrudService[F,App.Domain,App.Create]
}
    [F[_]] => (client: KeystoneClient[F]) => client.domains

似乎是个错误。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。