简体   繁体   English

为Scala中的类型别名提供隐式证据

[英]Provide implicit evidence for a type alias in Scala

Is there a way to get the compiler to somehow consider type aliases when looking for implicit evidence? 有没有一种方法可以让编译器在寻找隐式证据时以某种方式考虑类型别名?

Here is an example of problem I am trying to solve: 这是我要解决的问题的一个示例:

// Third party library
class Foo[T, P]
class FooOps[FTP, T] {
  def apply[F[_, _], P](t: T)(implicit ev: F[T, P] =:= FTP): FTP = ???
}

type StringFoo = Foo[String, Boolean]
object StringFoo extends FooOps[StringFoo, String]

StringFoo("hello")

// Attempt to wrap the third party type but have the same ops
class WrappedFoo[FTP](val foo: FTP)
object WrappedFoo {
  type F[T, P] = WrappedFoo[Foo[T, P]]
}

type WrappedStringFoo = WrappedFoo[StringFoo]
object WrappedStringFoo extends FooOps[WrappedStringFoo, String]

WrappedStringFoo("hello") // Cannot prove that F[String, P] =:= WrappedStringFoo
WrappedStringFoo[WrappedFoo.F, Boolean]("hello”) // This works

I don't quite understand how the compiler infers the types in: 我不太了解编译器如何推断以下类型:

StringFoo("hello")

Does it somehow use the available implicits to choose a value for F[_, _] ? 是否以某种方式使用可用的隐式为F[_, _]选择一个值? I always thought that it had to work out the types first. 我一直认为它必须首先确定类型。

However it works for StringFoo it doesn't work for WrappedStringFoo . 但是它适用于StringFoo ,不适用于WrappedStringFoo Likely since the number of type parameters is different. 可能因为类型参数的数量不同。

How can I get: 我怎样才能得到:

WrappedStringFoo("hello")

to compile without specifying the types explicitly? 编译而不显式指定类型?

Try to add necessary implicit to scope: 尝试将必要的隐式添加到范围:

import scala.language.higherKinds

class Foo[T, P]
class FooOps[FTP, T] {
  def apply[F[_, _], P](t: T)(implicit ev: F[T, P] =:= FTP): FTP = ???
}

type StringFoo = Foo[String, Boolean]
object StringFoo extends FooOps[StringFoo, String]

class WrappedFoo[FTP](val foo: FTP)
object WrappedFoo {
  type F[T, P] = WrappedFoo[Foo[T, P]]

  //implicit val ev0: WrappedFoo.F[String, Boolean] =:= WrappedStringFoo = ???
  implicit val ev0: WrappedFoo.F[String, Boolean] =:= WrappedStringFoo = 
    null.asInstanceOf[WrappedFoo.F[String, Boolean] =:= WrappedStringFoo]
}

type WrappedStringFoo = WrappedFoo[StringFoo]
object WrappedStringFoo extends FooOps[WrappedStringFoo, String]

WrappedStringFoo("hello") 

When you do StringFoo("hello") compiler solves equation F[String, P] = Foo[String, Boolean] and it's smart enough to deduce P = Boolean , F = Foo . 当您执行StringFoo("hello")编译器会求解方程式F[String, P] = Foo[String, Boolean] ,它足够聪明地推论出P = BooleanF = Foo But when you do WrappedStringFoo("hello") compiler has to solve equation F[String, P] = WrappedFoo[Foo[String, Boolean]] and algorithms it uses are not smart enough to deduce P = Boolean , F = ({ type λ[A, B] = WrappedFoo[Foo[A, B]] })#λ ie WrappedFoo.F (and possibly such equations can't be solved in general if they are advanced enough). 但是,当您执行WrappedStringFoo("hello")编译器必须求解方程F[String, P] = WrappedFoo[Foo[String, Boolean]] ,其使用的算法不足以推论出P = BooleanF = ({ type λ[A, B] = WrappedFoo[Foo[A, B]] })#λWrappedFoo.F (并且如果这样的方程式足够先进,则可能一般无法求解)。 So you should provide a hint. 因此,您应该提供一个提示。 Either specifying type parameters explicitly or providing necessary implicit evidence. 明确指定类型参数或提供必要的隐式证据。

Resolving implicits and type inference make impact on each other. 解析隐式和类型推断会相互影响。 You can read section 4.4.3 of Eugene Burmako's thesis . 您可以阅读Eugene Burmako 论文的 4.4.3节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Scala:类型参数类的隐式证据 - Scala: Implicit evidence for class with type parameter Scala编译错误-找不到类型为证据的隐式值 - Scala compile error - could not find implicit value for evidence parameter of type Scala:泛型类型的隐式证据 - Scala: Implicit evidence for generic types Scala:BigDecimal是数字的隐式证据 - Scala: Implicit evidence that BigDecimal is Numeric 在Scala中键入别名优化跳过隐式转换? - Type alias optimization skipping implicit conversion in Scala? Scala:具有可遍历值的Map的隐式证据? - Scala: Implicit evidence of Map with Traversable values? 什么是Scala中的隐式证据? 到底有什么好处呢? - What is implicit evidence in Scala? What is it good for? Scala编译器如何用`&lt;:&lt;`综合隐式证据? - How does the Scala compiler synthesize implicit evidence with `<:<`? 斯卡拉<console> :24: 错误: 找不到微风.storage.DefaultArrayValue [Any] 类型的证据参数的隐式值 - Scala <console>:24: error: could not find implicit value for evidence parameter of type breeze.storage.DefaultArrayValue[Any] Scala / specs2:找不到 AsExecution[ExecutionEnv =&gt; MatchResult[Future[AuthenticationResult]]] 类型的证据参数的隐式值 - Scala / specs2 : could not find implicit value for evidence parameter of type AsExecution[ExecutionEnv => MatchResult[Future[AuthenticationResult]]]
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM