Imran K
Imran K

Reputation: 81

Cats Writer type-mismatch in for expression

I've created a type

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

My function called process wants to works on a list of Inputs and return 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 is a case class:

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

What I'm getting is these compiler error:

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

What I am doing wrong?

Update:

After reading the comments, I changed my function to combine the double values rather than just passing as it is. This compiles fine :

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

}

Upvotes: 1

Views: 234

Answers (1)

Dionysis Nt.
Dionysis Nt.

Reputation: 955

You cannot use <- operator for different data types inside a for comprehension. Try using = instead.

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

Upvotes: 0

Related Questions