加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 使用无形Mapper而无需指定结果类型

发布时间:2020-12-16 19:23:40 所属栏目:安全 来源:网络整理
导读:对于习惯于 Scala类型级编程的开发人员来说,这似乎是一个经典问题,但我找不到(或者我不知道如何搜索)解决方案或模式.假设我有一个这样的类: abstract class TypedTest[Args : HList](implicit val optMapper: Mapped[Args,Option]) { type OptArgs = optMap
对于习惯于 Scala类型级编程的开发人员来说,这似乎是一个经典问题,但我找不到(或者我不知道如何搜索)解决方案或模式.假设我有一个这样的类:

abstract class TypedTest[Args <: HList](implicit val optMapper: Mapped[Args,Option]) {
  type OptArgs = optMapper.Out

  def options: OptArgs // to be implemented by subclasses
}

我希望此类的用户使用HList类型参数(Args)对其进行实例化,并且该类提供了一种方法来检索包含Option(OptArgs)中每个指定类型的实例的HList实例.我正在使用无形的Mapped类型.请注意,我没有在实例化时提供Args的实例.

此代码不起作用,因为编译器不会推断OptArgs的具体类型,甚至一个明显正确的实现,如def options = HNil会产生编译错误.使用Aux模式的相同代码:

abstract class TypedTest[Args <: HList,OptArgs <: HList](implicit val optMapper: Mapped.Aux[Args,Option,OptArgs]) {
  def options: OptArgs
}

这迫使我在实例化时指定两个列表,这使得外部API不必要地冗长.这有解决方法吗?

解决方法

这是我的理解,但我不是百分百肯定,并且很乐意经过纠正.

类型成员TypedTest.OptArgs不是抽象类型,而是类型别名.对于TypedTest的所有子类,它是相同的类型 – Mapped [Args,Option] .Out的别名,它是一种抽象类型,不能与任何类型本身统一.创建子类时,不会覆盖类型成员OptArgs.

当使用Mapped.Aux和Out0的存在类型时,它变得更加清晰,这是IIUC或多或少等同于上面的:

abstract class TypedTest[Args <: HList](
    implicit val optMapper: Mapped.Aux[Args,T] forSome { type T }) {

  type OptArgs = optMapper.Out

  def options: OptArgs // to be implemented by subclasses
}

val intTest = new TypedTest[Int :: HNil] {
  def options = Some(1) :: HNil
}

Error:(18,29) type mismatch;
found   : shapeless.::[Some[Int],shapeless.HNil]
required: this.OptArgs
  (which expands to)  T
    def options = Some(1) :: HNil

不幸的是,我不知道任何可能的解决方案,除了将Out作为类型参数添加或将OptArgs定义为抽象类型并在每个子类中明确指定它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读