Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 选项[io.databaker.env.EnvValue],但类型F在类型中是不变的_Scala_Scala Cats - Fatal编程技术网

Scala 选项[io.databaker.env.EnvValue],但类型F在类型中是不变的

Scala 选项[io.databaker.env.EnvValue],但类型F在类型中是不变的,scala,scala-cats,Scala,Scala Cats,我有以下未编译的代码段: 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] } 编译器抱怨: [er

我有以下未编译的代码段:

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]
[error]找到:F[None.type]
[错误]必需:F[选项[io.databaker.env.EnvValue]]
[错误](扩展为)F[选项[io.databaker.env.EnvValue.Type]]

[错误]注意:None.type这是一个最小化的问题示例,显示引入
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)
您还可以编写类似于
Option.empty[String].pure[F]
之类的内容。遇到这种问题有很多方法(太精确的类型推断),有很多方法可以解决这个问题,您应该选择哪种方法主要取决于您的品味

我已更改为覆盖
def get(v:env.EnvVariable):F[Option[env.EnvValue]]=F.pure(None)
,并收到错误消息
notfound:value F
。我做错了什么

考虑在
隐式F:Applicative[F]

def foo[F[_]](implicit F: Applicative[F]): F[Option[String]] = F.pure(None)
        |              |              |                        |
      type           value          type                 "type as value"
注意参数
F
类型参数
F
具有相同的名称。现在对value
F
调用方法看起来就像是对类型调用方法一样

F.pure(None)
在Scala中,使用点语法调用类型上的方法是不可能的,但从概念上讲,这就是我们正在做的——我们希望传达调用“类型级别”函数的想法。这是因为值和类型存在于两个不同的世界中,因此我们可以重用相同的名称而不会发生冲突。例如,考虑为什么以下是合法的

scala> object f { def f[f](f: f): f = f }
     | val Int: Int = 42
object f
val Int: Int = 42              
现在,当使用上下文绑定的
符号时

def foo[F[_]: Applicative]: F[Option[String]] = Applicative[F].pure(None)
我们没有使用隐式值参数的名称,因此不能使用上述约定的技巧和调用

F.pure(None)
因为,同样,类型上的点表示法严格来说是非法的,所以我们使用带有main方法技巧的伴随对象

Applicative[F].pure(None)
这是因为
Applicative
companion有如下功能

Applicative {
  def apply[F[_]](implicit instance: Applicative[F]): Applicative[F] = instance
}
这么叫

Applicative.apply[F]
或更短

Applicative[F]
返回范围中的隐式
实例
。在这一点上,我们确实有我们的价值,所以点符号成为法律

Applicative[F].pure(None)
              |
    ok because invoked on a value

因此,您必须使用
Sync[F].pure(None)
而不是
F.pure(None)
调用,因为在您的特定情况下,您使用的是上下文边界。

在我上面的示例中,我已更改为
覆盖def get(v:env.EnvVariable):F[Option[env.EnvValue]=F.pure(None)
并收到错误消息
未找到:值F
。我做错了什么?Scala中的
x.type
是什么意思?@zero\u编码如果要显式引用
F
,需要使用隐式参数列表(如上面的第二个示例所示),而不是上下文绑定(
F[\uu]:Applicative
x.type
x
的单例类型,在
None的情况下,type
None
作为其唯一成员的类型。请您解释一下
F
上下文中类型和值之间的差异。示例<代码> DEFO [F[[A] ](隐式F:应用[f]):F[Optr[Str] ] = F.Prime:(无)< />代码,为什么<代码> f < /代码>也是一个值?@ ZoooLoad考虑为什么下面是合法的:<代码> ValIt:int=42 。这里的
Int
是用于值和类型的名称。因为
Int
是值,同时也是
类型@马里奥·加利克,你太棒了。
Applicative[F].pure(None)
              |
    ok because invoked on a value