[英]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 = Boolean
, F = 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 = Boolean
, F = ({ 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.