【问题标题】:Cats Writer type-mismatch in for expressionCats Writer for 表达式中的类型不匹配
【发布时间】:2019-09-26 04:16:31
【问题描述】:

我创建了一个类型

type ResultLog = Writer[List[String], Option[Double]]

我的函数process 想要在Inputs 列表上工作并返回ResultLog

def process(inputs : List[Input]): ResultLog = {

    for {
      input <- inputs
      res <- if(input.date == "28092018"){
        Writer(List(s"Wrong date ${input.date} of ${input.id} "), None)
      } else {
       Writer(Nil, Some(input.value))
      }
    } yield res
  }

Input 是一个案例类:

case class Input(date:String, id: Int, value : Double)

我得到的是这些编译器错误:

Error:(14, 11) type mismatch;
 found   : _2(in value $anonfun) => _2(in value $anonfun) where type _2(in value $anonfun) >: None.type with Some[Double] <: Option[Double]
 required: (some other)_2(in value $anonfun) => ? where type (some other)_2(in value $anonfun) >: None.type with Some[Double] <: Option[Double]
      res <- if(input.date == "28092018"){
Error:(14, 11) type mismatch;
 found   : _2(in value $anonfun) => _2(in value $anonfun) where type _2(in value $anonfun) >: None.type with Some[Double] <: Option[Double]
 required: _2(in value $anonfun) => ? where type _2(in value $anonfun) >: None.type with Some[Double] <: Option[Double]
      res <- if(input.date == "28092018"){
Error:(13, 13) type mismatch;
 found   : List[Nothing]
 required: Aggregation.this.ResultLog
    (which expands to)  cats.data.WriterT[cats.Id,List[String],Option[Double]]
      input <- inputs

我做错了什么?

更新:

阅读 cmets 后,我更改了函数以组合双精度值,而不是按原样传递。这编译得很好:

type ResultLog[A] = Writer[Vector[String], A]

def process2(inputs  :List[Input]): ResultLog[Option[Double]] = {
import cats.syntax.applicative._
import cats.instances.vector._

inputs.foldLeft(Writer(Vector(""),Option(0.0))){
  (z , i) => {
    if(i.cobDate == "28092018") {
      Writer(Vector(s"Wrong cobdate ${i.cobDate} of reportingSetId: ${i.reportingSetId}"), None)
    } else {
      z.value.flatMap(zv => Some(zv + i.value)).pure[ResultLog]
    }
  }
}

}

【问题讨论】:

  • 不清楚process 应该做什么。对于每个输入,您都有 log 或 double 值的消息。也许您想连接日志。但是您想对所有双精度值做什么?
  • process 所做的没有多大意义,我只是想了解如何在我有输入列表的情况下使用cats.Writer,其中一些可能会失败我将记录一条消息,对于其余的输入,我可能会合并双精度值。

标签: scala scala-cats writer-monad


【解决方案1】:

您不能对 for 理解中的不同数据类型使用 运算符。尝试改用 =

for {
      input <- inputs
      res = if(input.date == "28092018"){ // Use = instead of <-
        Writer(List(s"Wrong date ${input.date} of ${input.id} "), None)
      } else {
       Writer(Nil, Some(input.value))
      }
    } yield res

【讨论】:

  • 那么process的返回类型不是ResultLog
  • 当然。 for 理解相当于做inputs.map(input=&gt; doStuff)。因此,此代码块为列表的 每个 元素返回一个 ResultLog。如果您将返回类型更改为List[ResultLog],它将编译,但不确定您想要做什么
  • 好的,正如我之前所说,我正在尝试找到一种方法来从process 返回类型ResultLog。假设如果日期不是特定日期(例如 28092018),我将添加所有 input.value,在这种情况下将没有消息。但在输入中,如果其中一个的日期为 28092018,那么我将停止在该点添加双精度,并通过消息返回该值:wrong date 28092018 of $id
猜你喜欢
  • 1970-01-01
  • 2020-02-17
  • 1970-01-01
  • 2017-05-15
  • 2021-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多