我有一个关于暗示解决方案的问题。 说,我有以下类型类:
trait Foo[In <: Base, Out <: Base] {
def factor : Double
}
,而
sealed trait Base
object Base {
implicit def symmetricFoo[In <: Base, Out <: Base](implicit foo : Foo[In, Out]) : Foo[Out, In] =
new Foo[Out, In] {
def factor : Double = 1.0 / foo.factor
}
implicit def transitiveFoo[In <: Base, Mid <: Base, Out <: Base](implicit foo1 : Foo[In, Mid], foo2 : Foo[Mid, Out]) : Foo[In, Out] =
new Foo[In, Out] {
def factor : Double = foo1.factor * foo2.factor
}
}
case object A extends Base
case object B extends Base {
implicit def bFoo : Foo[B.type, A.type] =
new Foo[B.type, A.type] {
def factor : Double = 2.0
}
}
case object C extends Base {
implicit def cFoo : Foo[C.type, A.type] =
new Foo[C.type, A.type] {
def factor : Double = 3.0
}
}
case object D extends Base {
implicit def dFoo : Foo[D.type, C.type] =
new Foo[D.type, C.type] {
def factor : Double = 5.0
}
}
如果我在从X到Y的路径上有中间Foo,我希望能够获得Foo [X,Y]的实例。有时它确实有用,例如。克。
println(implicitly[Foo[D.type, A.type]].factor) // 15.0 (D->C, C->A = 5 * 3)
println(implicitly[Foo[D.type, B.type]].factor) // 7.5 (D->C, C->A, A->B = 5 * 3 * 1/2)
但如果我更改了行的顺序,则不会:
println(implicitly[Foo[D.type, B.type]].factor) // 7.5
println(implicitly[Foo[D.type, A.type]].factor) // does not compile
有很多或多或少相同的错误消息,如
test.this.Base.transitiveFoo不是test.Foo [test.C.type,test.A.type]的有效隐含值,因为:hasMatchingSymbol报告错误:类型test.Foo [test。]的隐式扩展分歧。 C.type,Mid]从对象Base中的方法transitiveFoo开始
对于类型test.Foo [test.A.type,Mid]的分支隐式扩展,从对象Base中的方法transitiveFoo开始
隐含的方法参数不足:(隐式e:test.Foo [test.D.type,test.A.type])test.Foo [test.D.type,test.A.type]。未指定的值参数e。
完整日志有点长。
给定Foo [X,Y]得到Foo [Y,X],给定Foo [X,Y]和Foo [Y,Z]得到Foo [X,Z]的正确方法是什么?对于任何定义Foo的组合? 像没有形状的'懒惰的帮助吗?提前谢谢!
答案 0 :(得分:1)
此变体似乎有效:
#ifndef LRGRAPH_H
#define LRGRAPH_H
typedef struct lrgraph_node lrgraph_node;
typedef struct lrgraph_edge lrgraph_edge;
lrgraph_node* lrgraph_createNode(void *data, char *dataType, int (*compare)(lrgraph_node *other, lrgraph_node *current), lrgraph_edge *connected[], unsigned numEdges);
void lrgraph_printVersion();
#endif /*LRGRAPH_H*/
以防我的build.sbt:
import shapeless.Lazy
trait Foo[In <: Base, Out <: Base] {
def factor : Double
}
sealed trait Base
case object A extends Base
case object B extends Base
case object C extends Base
case object D extends Base
trait LowPriorityImplicits {
implicit def symmetricFoo[In <: Base, Out <: Base](implicit foo : Lazy[Foo[In, Out]]) : Foo[Out, In] =
new Foo[Out, In] {
def factor : Double = 1.0 / foo.value.factor
}
}
object Base extends LowPriorityImplicits {
implicit def bFoo : Foo[B.type, A.type] =
new Foo[B.type, A.type] {
def factor : Double = 2.0
}
implicit def cFoo : Foo[C.type, A.type] =
new Foo[C.type, A.type] {
def factor : Double = 3.0
}
implicit def dFoo : Foo[D.type, C.type] =
new Foo[D.type, C.type] {
def factor : Double = 5.0
}
implicit def transitiveFoo[In <: Base, Out <: Base, Mid <: Base](implicit foo1 : Foo[In, Mid], foo2 : Foo[Mid, Out]) : Foo[In, Out] =
new Foo[In, Out] {
def factor : Double = foo1.factor * foo2.factor
}
}
def main(args: Array[String]): Unit = {
println(implicitly[Foo[D.type, B.type]].factor)
println(implicitly[Foo[D.type, A.type]].factor)
}
7.5
15.0
def main(args: Array[String]): Unit = {
println(implicitly[Foo[D.type, A.type]].factor)
println(implicitly[Foo[D.type, B.type]].factor)
}
15.0
7.5