scala – 使用无形Mapper而无需指定结果类型
对于习惯于
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定义为抽象类型并在每个子类中明确指定它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |