多重隐式转换的交集:重新发明轮子?
好吧,公正的警告:这是我上个星期的荒谬问题的后续行动。 虽然我觉得这个问题不是很可笑。 无论如何,这里是:
以前的荒谬问题:
假设我有一些基类特征T
与子类A
, B
和C
,我可以声明一个集合Seq[T]
,例如,可以包含typesA
, B
和C
。 使子types更加明确,让我们使用Seq[_ <: T]
types的绑定语法。
现在,假设我有一个带有成员A
, B
和C
的typesTC[_]
(其中“member”表示编译器可以在隐式范围内find一些TC[A]
等)。 与上面类似,我想使用上下文绑定语法来声明Seq[_ : TC]
types的集合。
这不是合法的斯卡拉,试图模仿可能会让你感觉像一个坏人 。 记住,上下文绑定的语法(当正确使用的时候)parsing成隐式参数列表来定义类或方法,在这里没有任何意义。
新的前提:
所以让我们假设types实例(即隐式值)是不可能的,相反我们需要在这种情况下使用隐式转换。 我有一些typesV
(“v”应该代表“view”,fwiw),并且范围A => V
, B => V
和C => V
隐式转换。 现在我可以填充一个Seq[V]
,尽pipeA
, B
和C
是不相关的。
但是如果我想要一个可以隐式转换为视图V1
和V2
的东西的集合呢? 我不能说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")
从String
和Int
到Foo & Bar
types的隐式转换发生在序列填充时,然后在调用foobar.foo
和foobar.bar
时从Foo & Bar
到Foo
和Bar
的隐式转换发生。
目前的荒谬问题:
- 有没有人在任何地方实施过这种模式,还是我第一个白痴呢?
- 有没有更简单的方法来做到这一点,我一味的错过了?
- 如果没有,那么我将如何实施更一般的pipe道工程,以便我可以写
Seq[Foo & Bar & Baz]
? 这对于HList
似乎是一份工作。 - 额外的巨型组合奖金:在实施更一般的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