gpt4 book ai didi

scala - 在 doobie 中为 for-comprehension 编写可选查询?

转载 作者:行者123 更新时间:2023-12-04 23:03:03 27 4
gpt4 key购买 nike

我想在 doobie 中使用 for-comprehension 在一个事务中运行多个查询。就像是:

def addImage(path:String) : ConnectionIO[Image] = {
sql"INSERT INTO images(path) VALUES($path)".update.withUniqueGeneratedKeys('id', 'path')
}

def addUser(username: String, imageId: Optional[Int]) : ConnectionIO[User] = {
sql"INSERT INTO users(username, image_id) VALUES($username, $imageId)".update.withUniqueGeneratedKeys('id', 'username', 'image_id')
}

def createUser(username: String, imagePath: Optional[String]) : Future[User] = {
val composedIO : ConnectionIO[User] = for {
optImage <- imagePath.map { p => addImage(p) }
user <- addUser(username, optImage.map(_.id))
} yield user

composedIO.transact(xa).unsafeToFuture
}

我刚开始接触 doobie(和猫),所以我对 FreeMonads 不太熟悉。我一直在尝试不同的解决方案,但为了理解工作,看起来两个块都需要返回一个cats.free.Free[doobie.free.connection.ConnectionOp,?]。

如果这是真的,有没有办法将我的 ConnectionIO[Image](来自 addImage 调用)转换为 cat.free.Free[doobie.free.connection.ConnectionOp,Option[Image]] ?

最佳答案

对于您的直接问题,ConnectionIO定义为 type ConnectionIO[A] = Free[ConnectionOp, A] ,即这两种类型是等效的(不需要转换)。

您的问题是不同的,如果我们一步一步地执行代码,就可以很容易地看到。为简单起见,我将使用 Option您在哪里使用 Optional .

  • imagePath.map { p => addImage(p) } :
    imagePath是一个选项,并且 map使用 A => B转换 Option[A]Option[B] .

    addImage返回 ConnectionIO[Image] ,我们现在有一个 Option[ConnectionIO[Image]] ,即这是一个 Option程序,而不是 ConnectionIO程序。

    我们可以改为返回 ConnectionIO[Option[Image]]通过替换 maptraverse ,它使用 Traverse类型类,见 https://typelevel.org/cats/typeclasses/traverse.html有关其工作原理的一些详细信息。但一个基本的直觉是哪里 map会给你一个 F[G[B]] , traverse而是给你一个 G[F[B]] .从某种意义上说,它的工作原理类似于 Future.traverse来自标准库,但以更一般的方式。
  • addUser(username, optImage.map(_.id))
    这里的问题是给定的 optImage这是一个 Option[Image] ,及其 id字段,这是一个 Option[Int] , optImage.map(_.id) 的结果是 Option[Option[Int]] ,而不是 Option[Int]您的方法所期望的。

    解决这个问题的一种方法(如果它符合您的要求)是将这部分代码更改为
    addUser(username, optImage.flatMap(_.id))
    flatMap 可以“加入”一个 Option与另一个由其值创建的(如果存在)。

  • (注意:您需要添加 import cats.implicits._ 以获取 traverse 的语法)。

    总的来说,这里的一些想法是关于 Traverse的。 , flatMap等,对学习很有用,这方面的两本书是“Scala With Cats”( https://underscore.io/books/scala-with-cats/)和“Scala 函数式编程”( https://www.manning.com/books/functional-programming-in-scala)

    doobie 的作者最近也做了一个关于“效果”的演讲,这可能有助于提高你对 Option 等类型的直觉。 , IO等: https://www.youtube.com/watch?v=po3wmq4S15A

    关于scala - 在 doobie 中为 for-comprehension 编写可选查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48944446/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com