如何在 Kotlin 中的泛型类上创建一个 'andThen' 作为可组合性的中缀运算符?



问题陈述:我正在尝试跨两种类型重新创建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>

切勿向已在类定义中声明的函数添加任何类型变量。 切勿为类本身添加额外的接收器。

最新更新