Cats Writer类型不匹配,用于表达

时间:2019-05-08 12:15:00

标签: scala scala-cats writer-monad

我创建了一个类型

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

我的名为process的函数想在Input的列表上工作并返回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

我做错了什么?

更新

阅读注释后,我更改了功能以合并双精度值,而不仅仅是按原样传递。这样编译就可以了:

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]
    }
  }
}

}

1 个答案:

答案 0 :(得分:0)

您不能将 <-运算符用于a内的不同数据类型以进行理解。尝试改用 =

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