首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用for-comprehension来表达以下嵌套的未来

如何用for-comprehension来表达以下嵌套的未来
EN

Stack Overflow用户
提问于 2016-08-18 17:46:52
回答 1查看 535关注 0票数 0

我的问题是:有没有可能用for-comprehension来简化这个嵌套表达式?

代码语言:javascript
复制
run(dbAction).flatMap(insertedJobs => {
  Future.sequence(insertedJobs.map { job =>
    recordingBean.findStreamsForInterval(job.mediaSource, job.begin, job.end) map { stream =>
      if (stream.nonEmpty) {
        recordingBean.findRecordingLocationsForInterval(stream.head.stream, job.begin, job.end).map(recordingLocations =>
          recordingLocations.map(_.size.getOrElse(0L)).sum).flatMap { expectedSizeInBytes =>
          updateSize(job.id.get, expectedSizeInBytes)
        }
        job
      } else {
        job
      }
    }
  })
})
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-19 01:03:50

因为理解是强大的,但它们并不是你所认为的全能的嵌套杀手。

for-comprehension很有用,直到你不把SeqLike monads和non-SeqLike monads混合在一起。但是一旦你将它们混合在一起,你就回到了嵌套的世界。而且它将比以前更糟糕,因为for-comprehensions隐藏了细节。

我们举几个例子,

代码语言:javascript
复制
val listOfListOfInt = List(List(1, 2, 3), List(2, 3, 4))

val listOfInt = for {
  loi <- listOfListOfInt
  i <- loi
} yield i + 4

// This will work just fine
// listOfInt: List[Int] = List(5, 6, 7, 6, 7, 8) 

现在让我们混合使用ListFuture

代码语言:javascript
复制
val futureOfList = Future({ List(1, 2, 3) })

val iWillNotCompile = for {
  l <- futureOfList
  i <- list
} yield i + 4

// the above is equivalent to writing,
val iWillNotCompile = futureOfList.flatMap(l => l.map(i => i + 4))

// would have been following but does not make sense
// `Success(5, 6, 7)`

上面的代码不会编译,实际上也不应该编译。因为Future是一个non-SeqLike monad。我的意思是,如果上面的代码正常工作,它将是一个Success(5, 6, 7),这是没有意义的。

类似地,下面的代码将不起作用

代码语言:javascript
复制
val listOfFuture = List(Future({ 1 }), Future({ 2 }), Future({ 3 }) )

val iWillNotCompile = for {
  f <- listOfFuture
  i <- f
} yield i + 4

// this is equivalent to
val iWillNotCompile = listOfFuture.flatMap(f => f.map(i => i + 4)

// should have been following and it makes sense
// List(Success(5), Success(6), Success(7))

这个案例与上一个案例有很大的不同,因为它确认了常识,但仍然不会起作用。原因是SeqLike-MonadsFutureflatMapflattenmap有非常非常不同的实现。

所以..。如果你处理的是ListFutureOptionTry等的混合应用,那就远离for-comprehension。试着用一种更聪明的方式写你的代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39014981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档