Несоответствие типа EitherT + State - PullRequest
1 голос
/ 21 июня 2020

Я работаю над небольшой программой, используя Scala Cats. Я сталкиваюсь с множеством ошибок типа при попытке использовать EitherT с State и для понимания. Например:

import cats.data.{EitherT, State}
import cats.data.State.get

object Test {
  type IntState[T] = State[Int, T]
  type IntStateEither[T] = EitherT[IntState, String, T]

  val test: IntStateEither[Unit] = for {
    isValid <- EitherT.right(get.map((it: Int) => it % 2 == 0))
    _ <- if (!isValid) EitherT.leftT("invalid number") else EitherT.rightT(())  // *
  } yield ()
}

Что дает мне:

(...) Test.scala:12: type mismatch;
 found   : cats.data.EitherT[[A(in value <local Id>)]A(in value <local Id>),_1,Unit] where type _1 <: String
 required: cats.data.EitherT[[A(in class IndexedStateT)]cats.data.IndexedStateT[cats.Eval,Int,Int,A(in class IndexedStateT)],String,Unit]
one error found

Если я закомментирую строку, отмеченную (*) выше, этот код компилируется. Я думаю, что правильно следую инструкциям на веб-сайте Cats в разделе «От A или B до EitherT[F, A, B]», но нужно ли мне давать больше подсказок по типу? Если да, я не уверен, где их добавить.

Любые указатели приветствуются!

Я использую Cats 2.0.0 и Scala 2.13.2.

1 Ответ

2 голосов
/ 21 июня 2020

Кажется, проблема в том, что компилятор не может определить правильные типы для EitherT.leftT и EitherT.rightT. Вы можете исправить эти ошибки, используя явные типы, такие как: EitherT.rightT[IntState, String], или, если вам нужен только один вызов flatMap, кажется, что это явно работает:

val test: IntStateEither[Unit] =
  EitherT
    .right[String](State.get[Int].map(it => it % 2 == 0))
    .flatMap { isValid =>
      if (isValid) EitherT.rightT(())
      else EitherT.leftT("invalid number")
    }

PS: Возможно, стоит проверить, помогает ли bm4 .

...