Scala 编译器使用复杂类型参数推断过于具体的类型



我正在编写一个FRM,字段抽象F[_]

trait Query[A]
case class Field[A](name: String)
case class DBTable[T[_[_]]](fields: T[Field]) extends Query[T[Field]]
// example table
case class PersonalInfo[F[_]](name: F[String], age: F[Int])

我想使用递归方案执行查询重写,所以我需要定义一个模式函子,

trait QueryF[A, B]
case class DBTableF[T[_[_]], B](fields: T[Field]) extends QueryF[T[Field], B]

然后coalgebra将查询提升到其中:

type Coalgebra[F[_], A] = A => F[A]
def coalg[A]: Coalgebra[QueryF[A, ?], Query[A]] = {
case DBTable(fields) => DBTableF(fields)
}

这有效,但定义要以相反方向转换的algebra不会:

type Algebra[F[_], A] = F[A] => A
def alg[A]: Algebra[QueryF[A, ?], Query[A]] = {
case DBTableF(value) => DBTable[A](value)
}

ALG 函数抛出编译器错误,表示constructor of type controllers.thing.DBTableF[T,B] cannot be uniquely instantiated to expected type controllers.thing.QueryF[?,controllers.thing.Query[?]

这里怎么样:

import scala.language.higherKinds
trait Query[A]
case class Field[A](name: String)
case class DBTable[T[_[_]]](fields: T[Field]) extends Query[T[Field]]
trait QueryF[A, B]
case class DBTableF[T[_[_]], B](fields: T[Field]) extends QueryF[T[Field], B]
type Coalgebra[F[_], A] = A => F[A]
def coalg[A]: Coalgebra[({ type L[X] = QueryF[A, X]})#L, Query[A]] = {
case DBTable(fields) => DBTableF(fields)
}
type Algebra[F[_], A] = F[A] => A
def alg[A]: Algebra[({ type L[X] = QueryF[A, X]})#L, Query[A]] = {
case dbtf: DBTableF[t, b] => DBTable(dbtf.fields)
}

或者,将最后一个case替换为:

case dbtf: DBTableF[t, b] => DBTable[t](dbtf.fields)

如果这更清楚一点。

两种变体都使用 2.12.6 上的-Ypartial-unification进行编译。

最新更新