加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala中的TraversableOnce,Future和Option用于理解

发布时间:2020-12-16 08:55:43 所属栏目:安全 来源:网络整理
导读:我有一个表示DB记录的字符串ID列表.我想异步地从数据库加载它们,然后异步上传每个记录到远程服务器,然后当完成所有记录上传后,记录上传的记录的ID. 由于我使用的是Scala 2.9.2,我使用的是Twitter的core-util Future实现,但它应该与Monadic转换的2.10期货完全
我有一个表示DB记录的字符串ID列表.我想异步地从数据库加载它们,然后异步上传每个记录到远程服务器,然后当完成所有记录上传后,记录上传的记录的ID.

由于我使用的是Scala 2.9.2,我使用的是Twitter的core-util Future实现,但它应该与Monadic转换的2.10期货完全一样.

一般概念是这样的:

def fetch(id: String): Future[Option[Record]]
def upload(record: Record): Future[String]
def notifyUploaded(ids: Seq[String]): Unit

val ids: Seq[String] = ....

我试图通过for comprehension来做到这一点但fetch返回Future of Option这一事实使得它变得模糊不清并且代码无法编译:

for {
  id <- ids
  maybeRecord <- fetch(id)
  record <- maybeRecord
  uploadedId <- upload(record)
} yield uploadedId

编译此结果会导致以下错误:

scala: type mismatch;
found   : com.twitter.util.Future[String]
required: Option[?]
    uploadedId <- upload(record)
                  ^

我错过了什么?为什么编译器期望uploadId是一个选项?有什么好办法可以解决这个问题吗?

解决方法

考虑flatMap(或bind)函数的签名:

trait Monad[M[_]] {
  def flatMap[A](a : M[A],f : A => M[B]) : M[B]
  ....

在你的情况下,你试图在一个Option上使用flatMap,给它一个生成Future的f.但正如在上面的签名中,f应该在同一个monad中生成一些它被调用的东西.

Scala在这方面并不一定非常有用,因为它很好地将事物转换为(例如Seqs),使得你可以将任意flatMap调用链接在一起,无论容器如何.

你可能想要的是一个’Monad变换器’,它可以让你有一些组合monad的能力. Debasish Ghosh有一篇关于使用Scalaz monad变形金刚here的帖子.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读