Pat*_*iry 4 scala list-comprehension
据我所知,Scala for-comprehension符号依赖于第一个生成器来定义元素的组合方式.即,for (i <- list) yield i返回一个列表并for (i <- set) yield i返回一个集合.
我想知道是否有办法指定元素如何独立于第一个生成器的属性进行组合.例如,我想得到"给定列表中所有元素的集合",或"给定集合中所有元素的总和".我找到的唯一方法是首先构建一个列表或一个由for-comprehension符号规定的集合,然后对它应用一个转换函数 - 在这个过程中构建一个无用的数据结构.
我想到的是一种通用的"代数"理解符号,例如它存在于Ateji PX中:
`+ { i | int i : set } // the sum of all elements from a given set
set() { i | int i : list } // the set of all elements from a given list
concat(",") { s | String s : list } // string concatenation with a separator symbol
Run Code Online (Sandbox Code Playgroud)
这里,第一元件(`+,set(),concat(","))是一个所谓的"半群",它定义元素是如何组合,独立于所述第一发生器的结构的(也可以是多个发生器和滤波器,I只是试图保持例子简洁).
有关如何在Scala中实现类似结果同时保持简洁明智的表示的任何想法?据我所知,for-comprehension符号在编译器中是硬连线的,无法升级.
感谢您的反馈意见.
oxb*_*kes 12
在forScala中理解是调用语法糖flatMap,filter,map和foreach.与调用这些方法的方式完全相同,目标集合的类型会导致返回集合的类型.那是:
list map f //is a List
vector map f // is a Vector
Run Code Online (Sandbox Code Playgroud)
此属性是scala集合库的基本设计目标之一,在大多数情况下都会被视为可取.
您当然不需要构建任何中间集合:
(list.view map (_.prop)).toSet //uses list.view
(list.iterator map (_.prop)).toSet //uses iterator
(for { l <- list.view} yield l.prop).toSet //uses view
(Set.empty[Prop] /: coll) { _ + _.prop } //uses foldLeft
Run Code Online (Sandbox Code Playgroud)
将产生集合而不生成不必要的集合.我个人的偏好是第一个.在惯用的 scala集合操作方面,每个"集合"都带有以下方法:
//Conversions
toSeq
toSet
toArray
toList
toIndexedSeq
iterator
toStream
//Strings
mkString
//accumulation
sum
Run Code Online (Sandbox Code Playgroud)
最后一个用于集合的元素类型Numeric在作用域中具有隐式实例的情况; 如:
Set(1, 2, 3, 4).sum //10
Set('a, 'b).sum //does not compile
Run Code Online (Sandbox Code Playgroud)
请注意,scala中的字符串连接示例如下所示:
list.mkString(",")
Run Code Online (Sandbox Code Playgroud)
在scalaz FP库中可能看起来像(用于Monoid对字符串求和):
list.intercalate(",").asMA.sum
Run Code Online (Sandbox Code Playgroud)
你的建议看起来不像Scala; 我不确定他们是否受到另一种语言的启发.
| 归档时间: |
|
| 查看次数: |
920 次 |
| 最近记录: |