Functional programming 如何在Kotlin中使用兼容的参数/结果类型组合函数?
我有一个Functional programming 如何在Kotlin中使用兼容的参数/结果类型组合函数?,functional-programming,kotlin,Functional Programming,Kotlin,我有一个界面,看起来像这样: interface FontRegionTransformer<R> { fun transform(region: R, textCharacter: TextCharacter): R } var image = source.getSubimage(meta.x * width, meta.y * height, width, height) return combinedTransformers.invoke(image)
界面
,看起来像这样:
interface FontRegionTransformer<R> {
fun transform(region: R, textCharacter: TextCharacter): R
}
var image = source.getSubimage(meta.x * width, meta.y * height, width, height)
return combinedTransformers.invoke(image)
这是可行的,但我有一个问题:如何将fontregintransformer
s的列表
组合到单个函数中?我是否可以在不向界面添加compose
函数的情况下执行此操作?我用reduce
试过,但没有点击
澄清:我想实现的是将存储在regionTransformers
中的函数组合成一个函数,而不是这里的循环:
var image = source.getSubimage(meta.x * width, meta.y * height, width, height)
regionTransformers.forEach {
image = it.transform(image, textCharacter)
}
我想要这样的东西:
interface FontRegionTransformer<R> {
fun transform(region: R, textCharacter: TextCharacter): R
}
var image = source.getSubimage(meta.x * width, meta.y * height, width, height)
return combinedTransformers.invoke(image)
对于合成定义,不太清楚的是,当调用合成的转换器时,第二个
FontRegionTransformer
应该得到什么。在这里,我假设传入调用的是同一个textCharacter
,它自然地被传递到第一个转换器
您可以将自定义合成操作作为FontRegionTransformer
的扩展来实现:
要将变压器列表组合成一个列表,请使用:
“将
fontregintransformer
s的列表
组合为一个函数”是什么意思?您能指定您期望的输入和输出是什么吗?我编辑了我的问题。因此,如果不添加compose
函数,我就无法编写它们?我不能使用reduce
或其他映射函数来实现这一点吗?@AdamArold,因为它是一个自定义接口,您需要一个自定义函数来操作它的实例。:)库函数无论如何都不知道如何处理textCharacter
。即使对于内置函数类型,如(T)->R
,在kotlin stdlib
中也没有内置组合,但可以使用第三方函数编程库,如。顺便说一下,使用自定义的compose
函数,reduce
正是您接下来要做的事情。:)@AdamArold,如果您不喜欢单独的compose
函数,我已经添加了一个单语句解决方案,尽管它的可读性较差。
val composed = first.compose(second)
val transformers: List<FontRegionTransformer<SomeType>> = TODO()
val composition = transformers.reduce { a, b -> a.compose(b) }
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) }
}
}