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) }
    }
}