【问题标题】:Type lambda with higher kind类型更高的 lambda
【发布时间】:2021-01-07 16:20:19
【问题描述】:

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]
}

我想“简化”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, Model, Create] = f(client)
  }
}

但编译器抱怨:

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

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

Link to scastie with this code

PS:我不想再向BaseCreate 引入任何类型参数。尤其是F,因为这意味着Domain.Create 类必须是final case class Create[F[_]],这根本不是预期的解决方案。

【问题讨论】:

    标签: scala types dotty scala-3 polymorphic-functions


    【解决方案1】:

    我猜你把type lambdaspolymorphic functions 混淆了。

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

    对于类型 lambda,您应该使用 =&gt;&gt;,对于多态函数,您应该使用普通的 =&gt;(两次,即 [A] =&gt; (a: A) =&gt; 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
    

    似乎是一个错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多