用于从集合A构建集合B的惯用Scala

时间:2013-09-09 09:52:33

标签: scala

我有一个集合A,我需要从集合A创建集合B.在最简单的情况下,人们可能希望使用map方法,但我正在寻找一个解决方案,其中每一步都在要创建B的元素,需要访问集合中已有的元素。

我想到了创建B的多种可能性:

  • 为B使用可变集合,然后将其转换为不可变的
  • 使用集合B底层的构建器
  • 使用带有空B的foldLeft并在闭包内生长

是否存在惯用法,或者至少有一种方法可以根据不同的使用案例选择一种方法?

2 个答案:

答案 0 :(得分:6)

最惯用的是foldLeft - 折叠在函数式编程中非常自然。另一种可能性是scanLeft,这可能会略微减少簿记。

另一方面,这看起来真的是对State monad的迭代。这本书Functional Programming in Scala有一些非常类似于它的练习之一。

对于函数StateA monad基本上是类型为S => (S, A)的monad,尽管它通常被声明为一种正确的类型,其中包含一些特殊方法,使常见操作更容易。

在您的示例中,状态S将是最后结果的Option[A](或者,如果适用,则为A的“零”)。然后,您可以将您的集合从其T类型映射到S => (S, A)(或州monad类型)的函数中,获得Coll[S => (S, A)]

从那里你可以sequence sequence M[N[A]]可以将N[M[A]]变为M for monads NS => (S, Coll[A]) - 请参阅The Essence of the Iterator Pattern),获取Coll[A],将其提供给初始状态,然后检索foldLeft

网上有很多关于州monad的资源,不过我个人觉得比大多数其他monad更难掌握。有人提到我可能是因为“州”monad被错误命名,而且它实际上是一个“状态处理器”monad,这对我来说很有意义。

无论如何,从你的选择来看,{{1}}是最惯用的,但状态monad方法非常适合这项任务。

答案 1 :(得分:5)

我肯定会认为foldLeft是最惯用的方法。这正是我在阅读你的可能性之前所想到的。