当我在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> 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) 免责声明:下面的代码片段与正在进行的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) 应该通过用户检查用户的简单代码,用户是活动的,并且在更新上次登录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) 假设我有以下代码:
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的元组匹配吗?
在使用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中.
我正在研究用于关系(类似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) 鉴于以下方法......
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) 我有以下 ZIO 程序,其中包含两个永久运行的进程:
for {
..
numberProvider <- numberProvider(queue).fork // runs forever
numberService <- numberService(queue) // runs forever
..
} yield ()
Run Code Online (Sandbox Code Playgroud)
上面的代码有效,但我想知道这是否是好的做法。
有2个问题:
可以吗,在主程序上运行 2. 进程。或者它也应该是Fiber?
我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
我有一个用于剥香蕉的错误类型层次结构:
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 ×10
future ×2
apache-spark ×1
collections ×1
concurrency ×1
flatmap ×1
map ×1
rdd ×1
scala-cats ×1
scalding ×1
tuples ×1
zio ×1