标签: for-comprehension

Scala for-understanding中val的范围规则是什么?

当我在for-comprehension中使用val时,我收到警告:

警告:不推荐使用val关键字for comprehension

尽管在规范的语法附录中生成了.

这表明当我做类似的事情时

for (x <- xs; a = x)
Run Code Online (Sandbox Code Playgroud)

我并没有真正引入一个变量,比如我做的事情

for (x <- xs) yield { implicit val a = x; /* more */ }
Run Code Online (Sandbox Code Playgroud)

像往常一样,大括号开始一个新的范围,我可以引入一个新的val,甚至是一个新的隐含.

我到底在做什么a

我在消耗堆栈空间吗?堆?其他一些别名?

scala for-comprehension

6
推荐指数
1
解决办法
3004
查看次数

使用4(或N)个集合一次只能产生一个值(1xN)(即为tuple4 +压缩)

scala> val a = List(1,2)
a: List[Int] = List(1, 2)

scala> val b = List(3,4)
b: List[Int] = List(3, 4)

scala> val c = List(5,6)
c: List[Int] = List(5, 6)

scala> val d = List(7,8)
d: List[Int] = List(7, 8)

scala> (a,b,c).zipped.toList
res6: List[(Int, Int, Int)] = List((1,3,5), (2,4,6))
Run Code Online (Sandbox Code Playgroud)

现在:

scala> (a,b,c,d).zipped.toList
<console>:12: error: value zipped is not a member of (List[Int], List[Int], List[Int],     List[Int])
              (a,b,c,d).zipped.toList
                       ^
Run Code Online (Sandbox Code Playgroud)

我在其他地方搜索过这个,包括这个这个,但没有确定的答案.

我想做以下或类似的事情:

for((itemA,itemB,itemC,itemD) <- (something)) yield itemA + itemB …
Run Code Online (Sandbox Code Playgroud)

collections scala tuples for-comprehension

6
推荐指数
1
解决办法
709
查看次数

为什么这个未来的列表转换列表编译和工作?

免责声明:下面的代码片段与正在进行的Coursera课程之一相关.我们认为它只是出于学习目的而发布,不应该用于提交作为家庭作业的解决方案.

正如下面的评论所述,我们需要将Futures列表转换为列表的单个Future.更重要的是,如果至少有一个输入期货失败,那么最终的未来将会失败.

我遇到了以下实现,我完全不明白.

/** Given a list of futures `fs`, returns the future holding the list of values of all the futures from `fs`.
 *  The returned future is completed only once all of the futures in `fs` have been completed.
 *  The values in the list are in the same order as corresponding futures `fs`.
 *  If any of the futures `fs` fails, the resulting future also fails.
 */
def all[T](fs: List[Future[T]]): Future[List[T]] = 
             fs.foldRight(Future(Nil:List[T]))((f, fs2) =>
  for { …
Run Code Online (Sandbox Code Playgroud)

scala future for-comprehension

6
推荐指数
1
解决办法
2866
查看次数

Scala异步/回调代码重写

应该通过用户检查用户的简单代码,用户是活动的,并且在更新上次登录datetime之后.

  def authenticate() = Action.async { implicit request => 
    loginForm.bindFromRequest.fold(
        errors => Future.successful(BadRequest(views.html.logon(errors))),
        usersData =>{
           val cursor =  this.collection.find(BSONDocument("name" -> usersData._1)).one[Account].map(_.filter(p=>p.password == hashedPass(usersData._2, usersData._1)))
           cursor.flatMap(p => p match {
               case None => Future.successful(BadRequest(views.html.logon(loginForm.withGlobalError("user/pass incorect!!!"))))
               case Some(user) => {
                 if(!user.active) 
                   Future.successful(BadRequest(views.html.logon(loginForm.withGlobalError("inactive!!!"))))
                 else collection.update(BSONDocument("_id" -> user.id), 
                          BSONDocument("$set" -> 
                          BSONDocument("lastLogin" -> BSONDateTime(new org.joda.time.DateTime().getMillis()))))
                          .flatMap(x => gotoLoginSucceeded(user.id.stringify))

               }
               })
            })
  }  
Run Code Online (Sandbox Code Playgroud)

如何将它重写为较少flatMap/map spaghetti?

另一种方法

def authenticate() = AsyncStack { implicit request => 
loginForm.bindFromRequest.fold(
    errors => Future.successful(BadRequest(views.html.logon(errors))),
    usersData =>{
      for{
        user <- this.collection.find(BSONDocument("name" -> usersData._1)).one[Account].map(_.filter(p=>p.password …
Run Code Online (Sandbox Code Playgroud)

scala map for-comprehension playframework-2.0 flatmap

6
推荐指数
1
解决办法
402
查看次数

Scala的元组是正确的

假设我有以下代码:

val either: Either[String, (Int, Int)] = Right((1,2))
for {
  (a, b) <- either.right
} yield a + b
Run Code Online (Sandbox Code Playgroud)

当我在REPL中评估它时,我得到了

:13:错误:构造函数无法实例化为期望的类型; 发现:(T1,T2)必需:scala.util.Either [Nothing,(Double,Double)](a,b)< - a.right ^:14:错误:未找到:值a}产生a + b ^

为什么我有这样的错误?我不能模仿来自Either's right的元组匹配吗?

scala for-comprehension

6
推荐指数
1
解决办法
1215
查看次数

使用RDD进行理解时发出警告

在使用RDD进行扩展时我收到警告,我不确定这是不是我做错了.如果我这样做:

val sc = new SparkContext(...)

val anRDD = sc.parallelize(List(
  ("a", List(1, 2, 3)), 
  ("b", List(4), 
  ("c", List(5, 6))
)

for {
  (someString, listOfInts) <- anRDD
  someInt <- listOfInts
} yield (someString, someInt)
Run Code Online (Sandbox Code Playgroud)

然后我得到这个输出:

 warning: `withFilter' method does not yet exist on org.apache.spark.rdd.RDD[(String, List[Int])], using `filter' method instead
  (s, li) <- rl
Run Code Online (Sandbox Code Playgroud)

但它仍然成功返回FlatMappedRDD [(String,Int)].难道我做错了什么?或者忽略此警告是否安全?

更新:我也会接受for-comprehension如何将这些操作转换为map/flatMap/filter调用,因为我认为不需要任何过滤器或withFilter调用.我认为这相当于类似的东西:

anRDD.flatMap(tuple => tuple.map(someInt => (tuple._1, someInt)))
Run Code Online (Sandbox Code Playgroud)

但这不包括任何过滤器或withFilter调用,这似乎是警告的来源.

哦,我正在使用Spark 1.2.0,Scala 2.10.4,这都在REPL中.

scala for-comprehension apache-spark rdd

6
推荐指数
1
解决办法
1745
查看次数

为什么理解扩展为`withFilter`

我正在研究用于关系(类似SQL)运算符的DSL.我有一个Rep[Table]类型.apply: ((Symbol, ...)) => Obj,返回一个Obj定义.flatMap: T1 => T2.map: T1 => T3函数的对象的方法.由于类型Rep[Table]对基础表的模式一无所知,因此该apply方法就像投影一样 - 仅投影参数元组中指定的字段(很像无类型的烫印api).现在type T1是一个"类似元组",它的长度受到一些无形魔法约束到投影元组的长度,但是否则元组元素的类型由api用户决定,所以代码就像

val a = loadTable(...)
val res = a(('x, 'y)).map { (t: Row2[Int, Int]) =>
  (1, t(0))
}
Run Code Online (Sandbox Code Playgroud)

要么

val res = a(('x, 'y)).map { (t: Row2[String, String]) =>
  (1, t(0))
}
Run Code Online (Sandbox Code Playgroud)

工作良好.请注意,必须显式指定map/ flatMapfunction 的参数类型.但是,当我尝试用它来理解时

val a = loadTable(...)
val b = loadTable(...)
val c = loadTable(...) …
Run Code Online (Sandbox Code Playgroud)

scala for-comprehension scalding

6
推荐指数
1
解决办法
3139
查看次数

为了理解:如何顺序运行期货

鉴于以下方法......

def doSomething1: Future[Int] = { ... }
def doSomething2: Future[Int] = { ... }
def doSomething3: Future[Int] = { ... }
Run Code Online (Sandbox Code Playgroud)

......以及以下的理解:

for {
  x <- doSomething1
  y <- doSomething2
  z <- doSomething3
} yield x + y + z
Run Code Online (Sandbox Code Playgroud)

这三种方法并行运行,但在我的情况下doSomething2必须在doSomething1完成之后运行.如何按顺序运行这三种方法?

编辑

正如Philosophus42所建议的,下面是一个可能的实现doSomething1:

def doSomething1: Future[Int] = {
  // query the database for customers younger than 40;
  // `find` returns a `Future` containing the number of matches
  customerService.find(Json.obj("age" -> Json.obj("$lt" -> …
Run Code Online (Sandbox Code Playgroud)

scala future for-comprehension

6
推荐指数
1
解决办法
2466
查看次数

ZIO:如何加入 Fibers 以实现永久运行的流程

我有以下 ZIO 程序,其中包含两个永久运行的进程:

    for {
      ..
      numberProvider <- numberProvider(queue).fork  // runs forever
      numberService <- numberService(queue)         // runs forever
      ..
    } yield ()
Run Code Online (Sandbox Code Playgroud)

上面的代码有效,但我想知道这是否是好的做法。

有2个问题:

  1. 可以吗,在主程序上运行 2. 进程。或者它也应该是Fiber

  2. join最终是否必须使用 Fibers,即使它们永远运行,因此永远不会到达join?

    for {
      ..
      numberProvider <- numberProvider(queue).fork  // runs forever
      numberService <- numberService(queue)         // runs forever
      ..
      _ <- numberProvider.join // join in any case
    } yield ()
    
    Run Code Online (Sandbox Code Playgroud)

concurrency functional-programming scala for-comprehension zio

6
推荐指数
1
解决办法
596
查看次数

使用EitherT来评估使用共享错误类型继承的操作结果?

我有一个用于剥香蕉的错误类型层次结构:

sealed trait PeelBananaError
object PeelBananaError {
  case object TooRipe extends PeelBananaError
  case object NotRipeEnough extends PeelBananaError
}
Run Code Online (Sandbox Code Playgroud)

我有一些结果EitherT,我们知道只能以两种方式之一失败:

val peelBrownBananaResult: EitherT[Future, TooRipe, String] = ...
val peelGreenBananaResult: EitherT[Future, NotRipeEnough, String] = ...
Run Code Online (Sandbox Code Playgroud)

现在我需要String从右边收集结果并将它们组合起来以获得最终结果:

val combinedResult: EitherT[Future, PeelBananaError, String] = for {
  first <- peelBrownBananaResult
  second <- peelGreenBananaResult
} yield (first + second)
Run Code Online (Sandbox Code Playgroud)

但是尝试这个会给我一个编译错误:

cmd15.sc:2: inferred type arguments [PeelBananaError.NotRipeEnough.type,String] do not conform to method flatMap's type parameter bounds [AA >: PeelBananaError.TooRipe.type,D]
  first <- peelBrownBananaResult
           ^
cmd15.sc:2: …
Run Code Online (Sandbox Code Playgroud)

scala for-comprehension scala-cats

6
推荐指数
1
解决办法
72
查看次数