gpt4 book ai didi

scala - 在 Scala 函数式编程中,是否有一种惯用的方式来映射状态?

转载 作者:行者123 更新时间:2023-12-04 19:32:28 24 4
gpt4 key购买 nike

常规映射函数具有签名A => B,将F[A] 转换为F[B],例如,将 List[A] 转换为 List[B]

但是,如果映射函数应携带计算 B 所需的某些状态,您会怎么做?

例如,映射函数如下所示:(A, S) => (B, S),其中 S 是 State 的类型。对于每个 A,先前返回的 S 被传递到映射函数中,而最初为状态提供了一个 zero 元素。然后映射函数返回一个新状态(连同结果),然后再次将其与下一个值一起传递,依此类推。

当然,.map 还不够强大,所以解决方案必须基于另一个运算符。

为了便于说明,举一个具体的例子,假设我有一个 Int 序列,我想计算每个 Int 与前一个 的差值Int 在那个序列中。上述映射函数的实现如下所示:

  def mapping(currentElement: Int, previousElement: Option[Int]): (Option[Int], Option[Int]) = {
(previousElement.map(currentElement - _), Some(currentElement))
}

previousElement 的初始 值为None,在第一个元素之后它总是Some(currentElement) 。每次迭代的结果都是 Some 当前值减去最后一个值,除了第一个元素,它是 None

我如何将 List(1, 4, 3) 转换为 List(None, Some(3), Some(-1)) 使用映射函数?

(请注意,Int 减法示例仅用于说明目的,问题的重点是所描述操作类型的通用解决方案。)

最佳答案

Scala 2.13.x unfold() 方法维护一个与您的示例类似的状态。

List.unfold((Option.empty[Int], List(1, 4, 3))){
case (prev, hd::tl) => Some((prev.map(hd.-), (Some(hd),tl)))
case (prev, Nil) => None
}
//res0: List[Option[Int]] = List(None, Some(3), Some(-1))

这在 LazyListIterator 上可用,因此可用于创建伪无限流。

关于scala - 在 Scala 函数式编程中,是否有一种惯用的方式来映射状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61051884/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com