问题陈述:我正在尝试跨两种类型重新创建Scala/Finagle的andThen
方法链接/组合:过滤器和服务。
目标是能够做这样的事情:
val f1 = Filter1()
val f2 = Filter2()
val s3 = Service3()
val pipeline = f1 andThen f2 andThen s3
val result = pipeline(4) //execute pipeline with integer value of 4
过滤器应该可以与其他过滤器结合使用,也可以与"结束链"的服务结合使用。服务也应可与其他服务结合使用。两者似乎都会导致Unresolved reference andThen
现有的非工作解决方案:
typealias Transformer<A,B> = (A) -> B
abstract class Service<A,B>: Transformer<A,B> {
//DOESN'T WORK
infix fun <A,B,C> Service<A,B>.andThen(f: Service<B,C>): Service<A,C> {
val left = this
return object : Service<A, C>() {
override fun invoke(p1: A): C {
return f(left.invoke(p1))
}
}
}
}
typealias TwoWayTransformer<A,B,C,D> = (A, Service<C,D>) -> B
abstract class Filter<A,B,C,D>: TwoWayTransformer<A,B,C,D> {
//DOESN'T WORK
infix fun <A,B,E,F> Filter<A,B,C,D>.andThen(next: Filter<C,D,E,F>): Filter<A,B,E,F> {
val left = this
return object: Filter<A,B,E,F>() {
override fun invoke(a: A, service: Service<E,F>): B {
val s = object: Service<C,D>() {
override fun invoke(c: C): D { return next.invoke(c,service) }
}
return left.invoke(a,s)
}
}
}
//DOESN'T WORK
infix fun <A,B,C,D> Filter<A,B,C,D>.andThen(next: Service<C,D>): Service<A,B> {
val left = this
return object: Service<A,B>() {
override fun invoke(a: A): B {
return left.invoke(a, next)
}
}
}
}
侧 栏:
Filter<A,B,C,D>
可以用Filter<C,D,E,F>
缝制,也可以用Service<E,F>
缝合 - 最后两种类型的left
在做left andThen right
时必须与right
的前两种相匹配。
Filter<A,B,C,D>
只是类型的函数:(A, Service<C,D>) -> E
进一步简化为(A, C->D) -> E
链接到示例服务/过滤器的工作小提琴:https://pl.kotl.in/yIx80SzDF
您需要的签名是
infix fun <C> andThen(f: Service<B,C>): Service<A,C>
infix fun <E,F> andThen(next: Filter<C,D,E,F>): Filter<A,B,E,F>
infix fun andThen(next: Service<C,D>): Service<A,B>
切勿向已在类定义中声明的函数添加任何类型变量。 切勿为类本身添加额外的接收器。