【问题标题】:An abstract signature for "without" some type“没有”某种类型的抽象签名
【发布时间】:2014-02-16 11:15:36
【问题描述】:

我想要一个类型的方法来返回它混合的类型。例如,本着以下精神的东西:

trait A {
  def withoutA: this.type without A
}

所以在A with B with C 类型的情况下,withoutA 方法将有一个签名B with C,在A with D 的情况下 - 只是D

这是否可以实现?如果可以,如何实现?

这是一个如何使用它的示例:

trait Limit {
  def limit(a: Int): this.type without Limit
}
trait Offset {
  def offset(a: Int): this.type without Offset
}
val sqlBuilder = new Limit with Offset { ... }
sqlBuilder.limit(2).offset(4) // valid code
sqlBuilder.offset(4).limit(2) // valid code
sqlBuilder.limit(2).limit(4) // invalid code

【问题讨论】:

  • 你需要这个功能做什么? (只是想知道您认为这对什么有用)。
  • @Jesper 不容易描述。一个复合构建器,因此随着每个方法的应用而丢失方法。这提供了静态保证,即只有有意义的方法可用。
  • 这可以通过类型安全的构建器模式来完成。正如您可能发现的那样,对强制参数进行至少一次调用并不难,但很难只获得一次。我推荐 Jim McBeath 关于解决这个问题的三部分系列博客:jim-mcbeath.blogspot.com/2009/09/…

标签: scala mixins


【解决方案1】:

这里是在黑暗中刺伤,但类型 Negation as defined by shapeless 可能在这里工作。

type ¬[A] = A => Nothing

trait A {
  def withoutA: this.type with ¬[A]
}

虽然现在无法访问 REPL,但我还没有机会对此进行测试。我有兴趣了解用例。

更新:

如果您真正想要的是一个在您使用它们时逐渐减少可用操作的构建器,那么幻像类型和类型安全的构建器模式就会派上用场:

http://james-iry.blogspot.co.uk/2010/10/phantom-types-in-haskell-and-scala.html

http://blog.rafaelferreira.net/2008/07/type-safe-builder-pattern-in-scala.html

您可能还想更新问题的标题,以便其他人更容易找到:)

【讨论】:

  • 这篇博文很值得一读。但是,您提供的代码并没有解决问题,因为编译器将(new A with B {...}).withoutA 的类型视为Nothing,因此在该类型上看不到B 的任何成员。
  • 因此,基本上,隐式转换是在类型级别参数化的。一个非常好的主意。谢谢。但是我仍在寻找实际问题的答案。
  • 我是这里的软件工匠!回答实际要求是我的工作,而不仅仅是用户想问的问题:)
猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-12
相关资源
最近更新 更多