scala - Option[io.databaker.env.EnvValue],但类型 F 类型不变
问题描述
我有以下代码片段,它没有被编译:
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]
——有很多方法可以遇到这种问题(太精确的类型推断),还有很多方法可以解决它,你应该选择的主要是口味问题。
推荐阅读
- python - Plotly 自动滚动范围选择器
- java - Selenium 与 Java :stale 元素参考:元素未附加到页面文档
- c# - Line 类已过时,请改用 Polynomial 类
- python - 嵌套的 f 弦?
- arrays - 按值对 Javascript 条目进行排序
- ruby-on-rails - 将 Omniauth 与 Devise on Rails 6 一起使用时,为什么我会收到“无效的应用程序 ID 提供的应用程序 ID 看起来不像有效的应用程序 ID”的错误?
- rust - 为什么我在使用连接时得到 Vec<&&str> 的“不满意的特征界限”?
- r - 将 dplyr 链转换为函数
- javascript - 在底部时无法滚动元素
- java - 将 Avro Schema 转换为带有值的 JSON 有效负载