为啥 Scala 抱怨类型不匹配?

Posted

技术标签:

【中文标题】为啥 Scala 抱怨类型不匹配?【英文标题】:Why does Scala complain of type mismatch?为什么 Scala 抱怨类型不匹配? 【发布时间】:2021-06-27 03:36:09 【问题描述】:

我有一个类似的方法:

  private def _createConfig(
      app:            String,
): Future[Config] = 
    secret.map  secret =>
      Config(
        action        = s"SP_$app",
        clientSecret     = secret, 
      )
    
  

还有另一个消耗这个的方法:

  private def setup(
      app:                String,
      someCondition:      Boolean = false
  ): EitherT[Future, Throwable, String] = 
    Given("I create a partner")
    for 
      something <- createSomething()
      _ = if (someCondition) And(s"I do some action") else Done
      _ <- if (someCondition) createAnotherSomething(something) else doneEitherT

      _ = Then(s"I create a configuration for partner $partner and app $app")
      _ <- _createConfig(app)
      
     yield something
  

doneEitherT 定义为:

final lazy val doneEitherT = Future.successful(Done.upcast).rightT[Throwable]

当我构建它时,编译器会抱怨类型不匹配:

type mismatch;
 found   : scala.concurrent.Future[String]
 required: cats.data.EitherT[scala.concurrent.Future,Throwable,String]
      _ <- _createConfig(app)

为什么编译器期望_createConfig(app)EitherT 类型? for 块中的所有方法都应该与方法的签名匹配吗? Scala 新手并使用 Futures :/

【问题讨论】:

根据经验,for-comprehension 中&lt;- 的每个右侧都必须属于同一类型,因此在您的情况下为EitherT[Future, Throwable, A] 你能发个链接吗?即文档 - 我想更好地理解这一点 这是一个经验法则。如果您想获得更好的理解,请查看如何对理解进行脱糖,然后查看在 EitherT 上如何定义 flatMap 【参考方案1】:

正如 cmets 部分所建议的那样,用于理解的类型应该对齐并且编译器会抱怨:您在 EitherT 上调用 flatMap(隐式通过 &lt;-)并因此返回 Future而不是预期的EitherT

你需要改变返回类型并重新实现下一个方法:

private def _createConfig(app: String): EitherT[Future, Config, Throwable] = EitherT 
    secret.map  secret =>
      Right(Config(action = s"SP_$app", clientSecret = secret)
    
  

【讨论】:

这说明了很多!我改用EitherT.right[Throwable](_createConfig(app))(这行得通)。非常感谢!

以上是关于为啥 Scala 抱怨类型不匹配?的主要内容,如果未能解决你的问题,请参考以下文章

为啥此字段验证类型不匹配?

Scala的类型检查与拉姆达抱怨,不具有明确功能

为啥即使我有评估数据的条件,打字稿也会抱怨类型?

Scala多态函数类型不匹配

发现 scala 类型不匹配 Future[A] 预期 Future[B]

类型不匹配。必需:布尔值,在 Scala 中找到:Future[Boolean]