EitherT + State 类型不匹配

EitherT + State type mismatch

我正在使用 Scala Cats 开发一个小程序。我在尝试将 EitherTState 结合使用并进行理解时遇到了很多类型错误。例如:

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

如果我注释掉上面标记 (*) 的行,则此代码可以编译。我认为我正确地遵循了“从 ABEitherT[F, A, B]”下的说明 on the Cats website,但是我需要提供更多类型提示吗?如果是,我不确定在哪里可以添加它们。

非常感谢任何指点!

我正在使用 Cats 2.0.0 和 Scala 2.13.2。

问题似乎是编译器无法为 EitherT.leftTEitherT.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 是否有帮助