也许是具有结果累积的函子

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

我想为

Option
实现类似仿函数的东西,它可以积累成功的结果。

它的行为应该像这样(下面类似 scala 的代码):

Some(1).map(_ + 1) # => Some[(Int, Int)] = Some((1,2))
Some(1).map(_ + 1).map(_ * 3) # => Some[(Int, Int, Int)] = Some((1,2,6))
Some(1).map(_ => None) # Option[None.type] = Some(None)

do理解这不是一个合适的函子,因为它不保留身份:

Some(42).map(identity) # => Some[(Int, Int]) = Some((42, 42))

为了添加一些上下文,我认为当存在一系列地图时它会很有用:

val result = Some(42).map(compute_second_value).map(compute_third_value)

以及结果的模式匹配不仅取决于

result
最终值:

result match {
  case Some(value) => do_something_with_all_results(result._1, result._2, result._3)
  case None => ...
}

所以我正在寻找与所需行为相关的众所周知的解决方案/方法/理论术语

scala functional-programming
1个回答
0
投票

您可以使用 Scala 中的

foldLeft
以“通用”方式实现它,并处理序列而不是元组:

val ops: Seq[Int => Int] = Seq(computeSecondValue, computeThirdValue)

ops.foldLeft(Seq(1)) { case (acc, op) =>
  acc :+ op(acc.last)
}
// Seq[Int]
// Seq(1, computeSecondValue(1), computeThirdValue(computeSecondValue(1)))

或者采用不太通用的方法并保留元组:

for {
  first <- Some(1)
  second = computeSecondValue(first)
  third = computeThirdValue(second)
} yield (first, second, third)
// Option[Tuple3[Int, Int, Int]]

在这两种情况下,如果操作返回

flatMap
,我都没有管理
Option
情况,但这可以由读者相对轻松地实现。

© www.soinside.com 2019 - 2024. All rights reserved.