【问题标题】:Reduce a Collection List to single value Unit将集合列表简化为单值单元
【发布时间】:2021-07-04 05:07:05
【问题描述】:

我的值必须是 List[Unit] 类型的值,我该怎么做才能将其减少为 Unit

 def insertMany(users: List[User]) : IO[Unit] =
    lines.map(line => createorUpdate(user))
      .transact(xa)


def createorUpdate(user: User): ConnectionIO[Unit] =
    sql"""
          INSERT INTO $tableName ($columns)
          VALUES (${user.id}, ${user.age}, NOW(), NOW())
          ON CONFLICT DO NOTHING"""
      .update.run
      .map(_ => ())

这是完整的定义 我收到一个错误:

value transact is not a member of List[doobie.ConnectionIO[Unit]]
                       [error] possible cause: maybe a semicolon is missing before `value transact'?
                       [error]       .transact(xa)
                       [error]        ^
                       [error] one error found

【问题讨论】:

  • 扔掉然后返回Unit?只有 1 个单位值,因此无需对列表进行任何操作。
  • 除非您需要对列表中的每个元素执行一些副作用。然后你做list.foreach(_ => /* some side effect */)
  • 你为什么还要这样做?首先,您如何获得单位列表,使用 Unit 作为返回类型并不是一个好习惯。这就是拥有严格类型语言的全部意义所在。
  • 您可以使用ioList.void 将单位扔掉;虽然也许你应该早点完成 - 如果你使用 fs2.Stream 而不是 .compile.toList,则使用 .compile.drain
  • 你能添加一个例子吗?我猜你需要sequencetraverse_,因为你在谈论 IO 的 doobie

标签: list scala reduce


【解决方案1】:

听起来您正在寻找[updateMany][1],但有时这不起作用。

如果你想让你的代码工作,你需要将transact应用到IO

所以它必须是这样的:

def insertMany(lines: List[String]) : IO[Unit] =
    lines.map(line => createorUpdate(line)).sequence_.transact(xa)

sequence 基本上从 List[IO[your_type]] 变为 IO[List[your_type]]...

当您有 mapsequence_ 时,您始终可以转换为 traverse,所以这也可以工作

def insertMany(lines: List[String]) : IO[Unit] =
  lines.traverse_(line => createorUpdate(line)).transact(xa)

【讨论】:

    猜你喜欢
    • 2020-05-06
    • 1970-01-01
    • 2012-06-08
    • 2016-10-13
    • 2023-03-17
    • 2022-01-01
    • 2013-04-06
    • 2010-11-14
    • 1970-01-01
    相关资源
    最近更新 更多