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

Provide implicit evidence for a type alias in Scala

有没有办法让编译器在寻找隐含证据时以某种方式考虑类型别名?

这是我试图解决的问题示例:

// 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

我不太明白编译器是如何推断类型的:

StringFoo("hello")

它是否以某种方式使用可用的隐式来为 F[_, _] 选择一个值?我一直认为它必须先计算出类型。

但是它适用于 StringFoo 但不适用于 WrappedStringFoo。可能是因为类型参数的数量不同。

如何获得:

WrappedStringFoo("hello")

在不显式指定类型的情况下进行编译?

尝试向范围添加必要的隐式:

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") 

当您执行 StringFoo("hello") 时,编译器会求解方程 F[String, P] = Foo[String, Boolean],它足够聪明地推导出 P = BooleanF = Foo。但是,当您执行 WrappedStringFoo("hello") 时,编译器必须求解方程 F[String, P] = WrappedFoo[Foo[String, Boolean]],并且它使用的算法不够智能,无法推断出 P = BooleanF = ({ type λ[A, B] = WrappedFoo[Foo[A, B]] })#λ,即 WrappedFoo.F(可能还有这样的如果方程式足够先进,则一般无法求解)。所以你应该提供一个提示。明确指定类型参数或提供必要的隐含证据。

解析隐式和类型推断相互影响。您可以阅读 Eugene Burmako 的 thesis.

的第 4.4.3 节