Option[io.databaker.env.EnvValue],但类型 F 的类型不变

2024-04-05

我有以下代码片段,但未编译:

trait Environment[F[_]] {
  def get(v: EnvVariable): F[Option[EnvValue]]
}

final class LiveBadEnvironment[F[_] : Sync] extends Environment[F] {
  override def get(v: env.EnvVariable): F[Option[env.EnvValue]] = None.pure[F]
}

编译器抱怨:

[error]  found   : F[None.type]
[error]  required: F[Option[io.databaker.env.EnvValue]]
[error]     (which expands to)  F[Option[io.databaker.env.EnvValue.Type]]
[error] Note: None.type <: Option[io.databaker.env.EnvValue], but type F is invariant in type _.
[error] You may wish to define _ as +_ instead. (SLS 4.5)
[error]   override def get(v: env.EnvVariable): F[Option[env.EnvValue]] = None.pure[F]

我究竟做错了什么?


这是问题的最小化示例,显示了引入的导入pure扩展方法:

scala> import cats.Applicative, cats.implicits._
import cats.Applicative
import cats.implicits._

scala> def foo[F[_]: Applicative]: F[Option[String]] = None.pure[F]
                                                            ^
   error: type mismatch;
    found   : F[None.type]
    required: F[Option[String]]
   Note: None.type <: Option[String], but type F is invariant in type _.
   You may wish to define _ as +_ instead. (SLS 4.5)

问题是类型None.pure[F]被推断为F[None.type],没有预期返回类型影响推理。如果您对上下文绑定和扩展方法进行脱糖,类型推断将按您的预期工作:

scala> def foo[F[_]](implicit F: Applicative[F]): F[Option[String]] = F.pure(None)
def foo[F[_]](implicit F: cats.Applicative[F]): F[Option[String]]

你也可以写出类似的东西Option.empty[String].pure[F]等等——有很多方法可以遇到这种问题(过于精确的类型推断),也有很多方法可以解决它,而你应该选择哪种方法主要取决于个人喜好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Option[io.databaker.env.EnvValue],但类型 F 的类型不变 的相关文章

随机推荐