Scala中的一般理解
据我所知,Scala for-comprehension符号依赖于第一个生成器来定义元素的组合方式.即,对于(i< - list),yield i返回一个列表,并且对于(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 这里第一个元素(`,set(),concat(“,”))是一个所谓的“monoid”,它定义了元素的组合方式,与第一个生成器的结构无关(可以有多个生成器和过滤器,我只是试着保持简洁的例子). 有关如何在Scala中实现类似结果同时保持简洁明智的表示的任何想法?据我所知,for-comprehension符号在编译器中是硬连线的,无法升级. 感谢您的反馈意见. 解决方法
关于理解
scala中的for comprehension是对flatMap,filter,map和foreach的调用的语法糖.与调用这些方法的方式完全相同,目标集合的类型会导致返回集合的类型.那是: list map f //is a List vector map f // is a Vector 此属性是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 将产生集合而不生成不必要的集合.我个人的偏好是第一个.在惯用的scala集合操作方面,每个“集合”都带有以下方法: //Conversions toSeq toSet toArray toList toIndexedSeq iterator toStream //Strings mkString //accumulation sum 最后一个用于集合的元素类型在作用域中具有隐式Numeric实例的情况;如: Set(1,2,3,4).sum //10 Set('a,'b).sum //does not compile 请注意,scala中的字符串连接示例如下所示: list.mkString(",") 在scalaz FP库中可能看起来像(使用Monoid来汇总字符串): list.intercalate(",").asMA.sum 你的建议看起来不像Scala;我不确定他们是否受到另一种语言的启发. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |