据我所理解,Scala 的 for 推导符号依赖于第一个产生器来定义如何组合元素。即,
我想知道是否有一种方法可以独立于第一个生成器的属性来指定如何组合元素。例如,我想要获取给定列表中的所有元素的集合,或者给定集合中所有元素的总和。我找到的唯一方法是首先按照 for 推导符号的规定构建一个列表或集合,然后对其应用转换函数-在此过程中构建一个无用的数据结构。
我心目中的是一种通用的“代数”推导符号,例如 Ateji PX 中存在的。
这里的第一个元素(`+`,`set()`,`concat(",")`)是所谓的“幺半群”,它定义了元素如何组合,独立于第一个生成器的结构(可以有多个生成器和过滤器,我只是试图保持例子简洁)。
有什么想法可以在Scala中实现类似的结果,同时保持简洁明了的符号表示?据我所知,for-comprehension符号已经在编译器中被硬编码,无法升级。
感谢您的反馈。
for (i <- list) yield i
返回列表并且 for (i <- set) yield i
返回集合。我想知道是否有一种方法可以独立于第一个生成器的属性来指定如何组合元素。例如,我想要获取给定列表中的所有元素的集合,或者给定集合中所有元素的总和。我找到的唯一方法是首先按照 for 推导符号的规定构建一个列表或集合,然后对其应用转换函数-在此过程中构建一个无用的数据结构。
我心目中的是一种通用的“代数”推导符号,例如 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(",")`)是所谓的“幺半群”,它定义了元素如何组合,独立于第一个生成器的结构(可以有多个生成器和过滤器,我只是试图保持例子简洁)。
有什么想法可以在Scala中实现类似的结果,同时保持简洁明了的符号表示?据我所知,for-comprehension符号已经在编译器中被硬编码,无法升级。
感谢您的反馈。
(0 /: Set(1,2,3))(_ + _)
更习惯地写作Set(1,2,3).foldLeft(0)(_ + _)
或者更好的是Set(1,2,3).sum
。后一种形式是唯一真正声明式的构造,也是唯一在并行集合面前能够工作的形式。同样,(Set[Int]() /: List(1,2,3,2,1))((acc,x) => acc + x)
最好写成List(1,2,3,2,1).toSet
。 - Kevin Wright("" /: List("a", "b"))((acc,x) => acc + (if (acc == "") "" else ",") + x)
更好地编写为List("a", "b") mkString ","
。 - Kevin WrightfoldLeft
适合这个描述。sum
或toSet
存在的事实并不是我的重点,因为oxbow_lakes已经提到了这些内容。 - huynhjl