需要帮助理解 Kotlin Arrow 中的 mapOrAccumulate()

问题描述 投票:0回答:1

我正在使用 Kotlin 和 arrow-kt 编写一些代码,这些代码重复调用函数并收集结果。我在 arrow-core 中发现了一个名为 mapOrAccumulate() 的函数,它似乎是完成这项工作的正确工具。为了尝试一下,我制作了一个简单的演示函数和一些测试。我的演示代码如下所示:

fun checkAllEven( inputs:List<Int>): Either<NonEmptyList<Throwable>, List<Any>>
    {
        return inputs.mapOrAccumulate<Throwable, Int, Any> {
            println(it)
            checkEven(it)
        }
            
    }

fun checkEven( value:Int):Either<Throwable, String>
    {
        if( value % 2 != 0 )
        {
            return Either.Left( Throwable( "${value.toString()} not even!"))
        }
        else
        {
            return Either.Right("${value.toString()} even")
        }
    }

然后我使用以下方法进行测试:

@Test
fun testMapOrAccumulate()
{

    val inputs = listOf(0,1,2,3,4,5)

    checkAllEven(inputs).fold({
        println("left: $it")
    },{
        println("right: $it")
    })
}

我的期望是它将“失败”放在左边,将“成功”放在右边。相反,所有内容最终都会成为右侧的一个大列表,我的输出是:

right: [Either.Right(0 偶数), Either.Left(java.lang.Throwable: 1 不 偶数!),Either.Right(2偶数),Either.Left(java.lang.Throwable:3不 偶数!),Either.Right(4偶数),Either.Left(java.lang.Throwable:5不 甚至!)]

我在这里缺少什么?显然有一些我不明白的地方。

kotlin functional-programming accumulate arrow-kt
1个回答
0
投票

您需要在checkEven函数中

绑定
mapOrAccumulate
的结果:

fun checkAllEven( inputs:List<Int>): EitherNel<Throwable, List<String>>
{
   return inputs.mapOrAccumulate {
      println(it)
      checkEven(it).bind()
   }
}

绑定将返回两者的正确值。如果遇到左值,则会引发错误并累积。

经过此更改,输出如下所示:

left: NonEmptyList(java.lang.Throwable: 1 not even!,
  java.lang.Throwable: 3 not even!, java.lang.Throwable: 5 not even!)

您可以在Arrow文档

中找到更多详细信息
© www.soinside.com 2019 - 2024. All rights reserved.