多重隐式转换的交集:重新发明轮子?

好吧,公正的警告:这是我上个星期的荒谬问题的后续行动。 虽然我觉得这个问题不是很可笑。 无论如何,这里是:

以前的荒谬问题:

假设我有一些基类特征T与子类ABC ,我可以声明一个集合Seq[T] ,例如,可以包含typesABC 。 使子types更加明确,让我们使用Seq[_ <: T]types的绑定语法。

现在,假设我有一个带有成员ABC的typesTC[_] (其中“member”表示编译器可以在隐式范围内find一些TC[A]等)。 与上面类似,我想使用上下文绑定语法来声明Seq[_ : TC]types的集合。

这不是合法的斯卡拉,试图模仿可能会让你感觉像一个坏人 。 记住,上下文绑定的语法(当正确使用的时候)parsing成隐式参数列表来定义类或方法,在这里没有任何意义。

新的前提:

所以让我们假设types实例(即隐式值)是不可能的,相反我们需要在这种情况下使用隐式转换。 我有一些typesV (“v”应该代表“view”,fwiw),并且范围A => VB => VC => V隐式转换。 现在我可以填充一个Seq[V] ,尽pipeABC是不相关的。

但是如果我想要一个可以隐式转换为视图V1V2的东西的集合呢? 我不能说Seq[V1 with V2]因为我的隐式转换不会神奇般的聚集。

隐式转换的交集?

我解决了我的问题,像这样:

 // a sort of product or intersection, basically identical to Tuple2 final class &[A, B](val a: A, val b: B) // implicit conversions from the product to its member types implicit def productToA[A, B](ab: A & B): A = ab.a implicit def productToB[A, B](ab: A & B): B = ab.b // implicit conversion from A to (V1 & V2) implicit def viewsToProduct[A, V1, V2](a: A)(implicit v1: A => V1, v2: A => V2) = new &(v1(a), v2(a)) 

现在我可以像老板一样写Seq[V1 & V2] 。 例如:

 trait Foo { def foo: String } trait Bar { def bar: String } implicit def stringFoo(a: String) = new Foo { def foo = a + " sf" } implicit def stringBar(a: String) = new Bar { def bar = a + " sb" } implicit def intFoo(a: Int) = new Foo { def foo = a.toString + " if" } implicit def intBar(a: Int) = new Bar { def bar = a.toString + " ib" } val s1 = Seq[Foo & Bar]("hoho", 1) val s2 = s1 flatMap (ab => Seq(ab.foo, ab.bar)) // equal to Seq("hoho sf", "hoho sb", "1 if", "1 ib") 

StringIntFoo & Bartypes的隐式转换发生在序列填充时,然后在调用foobar.foofoobar.bar时从Foo & BarFooBar的隐式转换发生。

目前的荒谬问题:

  1. 有没有人在任何地方实施过这种模式,还是我第一个白痴呢?
  2. 有没有更简单的方法来做到这一点,我一味的错过了?
  3. 如果没有,那么我将如何实施更一般的pipe道工程,以便我可以写Seq[Foo & Bar & Baz] ? 这对于HList似乎是一份工作。
  4. 额外的巨型组合奖金:在实施更一般的pipe道,我可以限制types是独一无二的? 例如,我想禁止Seq[Foo & Foo]

附录失败:

我最近的尝试(主旨) 。 不可怕,但我不喜欢那里有两件事:

  • Seq[All[A :: B :: C :: HNil]]语法(我希望HList东西是不透明的,更喜欢Seq[A & B & C]
  • 转换所需的显式types注释( abc[A].a )。 似乎你可以有types推断或隐式转换,但不是两个…我不知道如何避免它,无论如何。

我可以给出点4的部分答案。这可以通过应用以下技术来获得:

http://vpatryshev.blogspot.com/2012/03/miles-sabins-type-negation-in-practice.html