从Here我们知道一个表达式:
for( i <- 1 to 10 ) yield i + 1
将扩展为
( 1 to 10 ).map( _+1 )
但是下面的表达式扩展到了什么?
for( i <- 1 to 50 j <- i to 50 ) yield List(1,i,j)
这是对的吗?
( 1 to 50 ).map( x => (1 to 50 ).map(List(1,x,_))
我对这个问题感兴趣,因为我想创建一个执行多个Xi <- Xi-1 to 50
操作的函数,如下所示:
for( X1 <- 1 to 50 X2 <- X1 to 50 X3 <- X2 to 50 ..... Xn <- Xn-1 to 50 )
yield List(1,X1,X2,X3,.....,Xn)
该函数有一个参数:dimension
表示上述表达式中的n
其返回类型为IndexSeq[List[Int]]
我怎样才能做到这一点?
感谢您的回答(:
答案 0 :(得分:5)
在相关的doc中对此进行了很好的解释。特别是:
for(x <- c1; y <- c2; z <- c3) yield {...}
将被翻译成
c1.flatMap(x => c2.flatMap(y => c3.map(z => {...})))
我不认为有一种方法可以抽象出任意嵌套理解(除非你使用巫毒魔法,就像宏一样)
答案 1 :(得分:0)
有关for循环扩展到的内容的解释,请参阅om-nom-nom的答案。我想回答开场问题的第二部分,如何实现可以执行的功能:
for( X1 <- 1 to 50 X2 <- X1 to 50 X3 <- X2 to 50 ..... Xn <- Xn to 50 )
yield List(1,X1,X2,X3,.....,Xn)
您可以使用:
def upto50(dimension: Int) = {
def loop(n: Int, start: Int): IndexedSeq[List[Int]] = {
if (n > dimension)
IndexedSeq(List())
else {
(n to 50).flatMap(x => loop(n + 1, x).map(x :: _))
}
}
loop(1, 1)
}
我们递归地计算每个循环,从内到外工作,从Xn to 50
开始并构建解决方案。
更常见案例的解决方案:
for( X1 <- S1 X2 <- S2 X3 <- S3 ..... Xn <- Sn )
yield List(1,X1,X2,X3,.....,Xn)
其中S1..Sn是任意序列或monad也是可能的。请参阅this gist以获取必要的代码墙。