【问题标题】:Scala: for-comprehension for chain of operationsScala:操作链的理解
【发布时间】:2022-01-01 01:58:03
【问题描述】:

我有一个任务来转换以下代码块:

  val instance = instanceFactory.create
  val result = instance.ackForResult

为了理解表达。

由于理解依赖于元素的枚举,我尝试使用包装类来解决它:

case class InstanceFactoryWrapper(value:InstanceFactory) {   
     def map(f: InstanceFactory => Instance): Instance
    = value.create()
 }

其中 map-method 必须只处理一个元素并返回一个结果:实例

我用这个表达式测试了这个方法:

 for {
     mediationApi <- InstanceFactoryWrapper(instanceFactoryWrapper)
}

但它不起作用:IDEA 建议我在这部分使用 foreach。但与 map 不同,“foreach”不返回任何内容。

我做错了什么?

【问题讨论】:

  • 你为什么要将工作代码更改为for 理解仅仅因为?! - 无论如何,这些表达式的类型是什么?
  • 我认为它是“链接”两个代码表达式的一种方式:第二个表达式使用第一个的结果。并且,当 2-d 完成但没有成功时,可能由于 1-t 表达式的格式错误而发生。
  • 但是您可以像instanceFactory.create.ackForResult 一样将它们链接起来。没有集合/异步计算/错误处理/其他类型的生产者可以证明.map 是合理的。我认为在您的原始情况下唯一可能的.map.flatMap 等是type Id[A] = A,直接在理解中使用是没有意义的。
  • @Andrew 您的代码在这方面有何不同?请注意,for 的目的是让一元组合看起来就像命令式代码(你有什么)

标签: scala for-comprehension


【解决方案1】:

简单地说,当使用 List\Option\Either 或其他语言类型时,理解对于将嵌套的 map\flatMap\withFilter 转换为序列很有用。

在理​​解中使用自定义类

但是您自己的课程或其他第 3 方的课程呢?

您需要实现一元操作才能在理解中使用它们。
最低限度:map 和 flatMap

以自定义 Config 类为例:

case class Config[T](content: T) {

  def flatMap[S](f: T => Config[S]): Config[S] =
    f(content)

  def map[S](f: T => S): Config[S] =
    this.copy(content = f(content))
}

for {
  first  <- Config("..")
  _      =  println("Going through a test")
  second <- Config(first + "..")
  third  <- Config(second + "..")
} yield third

这就是您启用理解的方式。

【讨论】:

    猜你喜欢
    • 2017-07-18
    • 2019-11-17
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 2013-06-03
    • 1970-01-01
    • 2018-05-19
    相关资源
    最近更新 更多