Kotlin基于扩展函数实现Applicative时ap方法输出不符问题
问题根源
你当前使用的ap是List类型的标准Applicative实现,语义是每个传入的函数都独立作用于原始列表的所有元素,你给出的第二个函数{ i -> i + 3 }是直接作用在原始数字上,而非和其他函数组合后作用,这是结果不符合预期的核心原因。
解决方案
你的需求本质是将函数列表中的函数按规则组合为复合函数后再应用,不需要修改原有ap实现,也不需要改动你已定义的函数列表,只需要在调用前生成符合你预期的复合函数列表传入ap即可。
从你给出的预期输出来看,你需要的是所有函数依次作用到每个元素上的效果,示例代码如下:
// 原有ap实现完全保留 fun <T, R> List<T>.ap(fab: List<(T) -> R>): List<R> = fab.flatMap { f -> this.map(f) } fun main(){ val numbers = listOf(75, 454, 7, 45, 45, 56, 75) // 原有函数列表定义完全保留 val functions = listOf<(Int) -> Int>({ i -> i * 2 }, { i -> i + 3 }) // 按你需要的规则生成复合函数列表:此处为两种组合顺序的复合函数 val applyAllInOrder: (Int) -> Int = functions.fold({ x: Int -> x }) { acc, func -> { func(acc(it)) } } val applyAllReversed: (Int) -> Int = functions.reversed().fold({ x: Int -> x }) { acc, func -> { func(acc(it)) } } val composedFunctions = listOf(applyAllInOrder, applyAllReversed) val result = numbers.ap(composedFunctions).joinToString() println(result) }
如果你的需求仅需要按函数列表定义的顺序依次应用所有函数,不需要反向组合,直接传入单元素的复合函数列表即可:
val composedFunc = functions.fold({ x: Int -> x }) { acc, func -> { func(acc(it)) } } val result = numbers.ap(listOf(composedFunc)).joinToString() // 输出:153, 911, 17, 93, 93, 115, 153
内容的提问来源于stack exchange,提问作者RidiX
相关产品推荐
相关产品推荐

