如何在 Kotlin 中使用兼容的参数/结果类型编写函数?



我有一个看起来像这样的interface

interface FontRegionTransformer<R> {
fun transform(region: R, textCharacter: TextCharacter): R
}

我不是范畴论方面的专家,但正如我之前所知道的,这个结构是一个幺半群(是吗?(,我可以组合任意数量的函数,这些函数一起R和返回R

这就是我现在拥有的:

var image = source.getSubimage(meta.x * width, meta.y * height, width, height)
regionTransformers.forEach {
image = it.transform(image, textCharacter)
}

这有效,但我有一个问题:如何将FontRegionTransformers 的List组合到单个函数中?我可以在不向界面添加compose函数的情况下做到这一点吗?我用reduce试了一下,但没有点击。

澄清:我想实现的是将存储在regionTransformers中的函数组合成一个函数,而不是这里的循环:

var image = source.getSubimage(meta.x * width, meta.y * height, width, height)
regionTransformers.forEach {
image = it.transform(image, textCharacter)
}

我想要这样的东西:

var image = source.getSubimage(meta.x * width, meta.y * height, width, height)
return combinedTransformers.invoke(image)    

对于组合定义,不太清楚,当调用组合转换器时,第二个FontRegionTransformer<R>应该得到什么textCharacter。在这里,我假设它是传递到调用中的相同textCharacter,并且自然地传递给第一个转换器。

您可以将自定义合成操作实现为FontRegionTransformer<R>的扩展:

fun <R> FontRegionTransformer<R>.compose(other: FontRegionTransformer<R>) =
object : FontRegionTransformer<R> {
override fun transform(region: R, textCharacter: TextCharacter): R {
val firstResult = this@compose.transform(region, textCharacter)
return other.transform(firstResult, textCharacter)
}
}

你可以将infix修饰符添加到compose以使用中缀表示法a compose b,或者让它重载运算符+*,如果你想把它称为a * b。或者使用非分机顶级函数进行compose(a, b)调用。

然后,您可以编写两个FontRegionTransformer

val composed = first.compose(second)

要将变压器列表组合成一个,请使用reduce

val transformers: List<FontRegionTransformer<SomeType>> = TODO()
val composition = transformers.reduce { a, b -> a.compose(b) }

对于幺半群的FontRegionTransformer<R>,组合操作应该是结合的(a ∘ (b ∘ c)应该等价于所有abc(a ∘ b) ∘ c(,上面的实现似乎满足了这个要求。但是,严格来说,它也应该有一个中立的元素,例如na ∘ n = n ∘ a = a任何a.这两个要求不能用 Kotlin 类型系统来表达,而应该是合同的一部分。


单语句解决方案是将compose内联到reduce调用中:

val composition = transformers.reduce { a, b ->
object : FontRegionTransformer<SomeType> {
override fun transform(region: SomeType, textCharacter: TextCharacter) =
a.transform(region, textCharacter).let { b.transform(it, textCharacter) }
}
}

相关内容

  • 没有找到相关文章

最新更新