【问题标题】:Scalaz: How to use EitherInstances with MonadError?Scalaz:如何将 EitherInstances 与 MonadError 一起使用?
【发布时间】:2018-01-14 08:34:48
【问题描述】:

我想将scala.util.Eitherscalaz.MonadError 一起使用,但我遇到了一些类型问题。 我最简单的失败代码如下:

object Foo extends EitherInstances {
  private val success: Either[String, Int] = Right(42)

  def main(args: Array[String]): Unit = {
    MonadError.apply(eitherMonad[String]).handleError[Int](success)(_ => Right(43))
  }
}

但是,这会导致以下无法解读的错误:

Error:(10, 16) no type parameters for method apply: (implicit F: scalaz.MonadError[F,S])scalaz.MonadError[F,S] in object MonadError exist so that it can be applied to arguments (scalaz.Traverse[[β$0$]scala.util.Either[String,β$0$]] with scalaz.MonadError[[β$1$]scala.util.Either[String,β$1$],String] with scalaz.BindRec[[β$2$]scala.util.Either[String,β$2$]] with scalaz.Cozip[[β$3$]scala.util.Either[String,β$3$]])
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : scalaz.Traverse[[β$0$]scala.util.Either[String,β$0$]] with scalaz.MonadError[[β$1$]scala.util.Either[String,β$1$],String] with scalaz.BindRec[[β$2$]scala.util.Either[String,β$2$]] with scalaz.Cozip[[β$3$]scala.util.Either[String,β$3$]]
 required: scalaz.MonadError[?F,?S]
    MonadError.apply(eitherMonad[String]).handleError[Int](success)(_ => Right(43))
Error:(10, 33) type mismatch;
 found   : scalaz.Traverse[[β$0$]scala.util.Either[String,β$0$]] with scalaz.MonadError[[β$1$]scala.util.Either[String,β$1$],String] with scalaz.BindRec[[β$2$]scala.util.Either[String,β$2$]] with scalaz.Cozip[[β$3$]scala.util.Either[String,β$3$]]
 required: scalaz.MonadError[F,S]
    MonadError.apply(eitherMonad[String]).handleError[Int](success)(_ => Right(43))

如果我尝试让编译器推断类型,例如,在以下代码中:

object Foo extends EitherInstances {
  private val success: Either[String, Int] = Right(42)

  def main(args: Array[String]): Unit = {
    MonadError.apply.handleError(success)(_ => Right(43))
  }
}

我收到以下错误:

Error:(11, 16) could not find implicit value for parameter F: scalaz.MonadError[F,S]
MonadError.apply.handleError(success)(_ => Right(43))
Error:(11, 16) not enough arguments for method apply: (implicit F: scalaz.MonadError[F,S])scalaz.MonadError[F,S] in object MonadError.
Unspecified value parameter F.
    MonadError.apply.handleError(success)(_ => Right(43))

由于eitherMonad 的结果明确声明自己是MonadError,我假设我在这里做错了什么。我需要做什么才能让编译器相信 Either 确实是 MonadError

【问题讨论】:

    标签: scala scalaz


    【解决方案1】:

    我假设我在这里做错了

    您需要启用Ypartial-unification,代码将在没有任何更改的情况下编译。

    sbt:

    scalacOptions in Compile ++= Seq("-Ypartial-unification")
    

    您还可以使用kind-projector 为类型 lambda 设置别名并帮助编译器:

    sbt:

    addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.4")
    

    然后:

    MonadError.apply[Either[String, ?], String].handleError(success)(_ => Right(43))
    

    【讨论】:

    • 行得通!有没有办法让它在没有显式类型的情况下编译?
    • @Gal 是的,启用部分统一(请参阅我的答案的第一部分 :))
    • @Gal 这有效:MonadError.apply(eitherMonad[String]).handleError[Int](success)(_ => Right(43)),但您仍然显式提供隐式:\
    • @Gal 注意,通过部分统一,你可以使用 MonadError 语法,只写success.handleError(_ => Right(43))
    • @Gal 这是一个 IntelliJ Scala 插件的错误。您可以开票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多