gpt4 book ai didi

Scala 编译器无法推断类型参数

转载 作者:行者123 更新时间:2023-12-01 12:59:57 26 4
gpt4 key购买 nike

为了为我的新 Scala 项目创建 DSL,我编写了以下代码:

trait DocDB[O] {
def searchFor[I] (docs: Iterable[I], queryStrategy: QueryStrategy[I, DocDB[_]]): Iterable[(I,O)]
}
trait QueryStrategy[I, +F <: DocDB[_]]

class In // class of input documents
class Out // class of output documents
// MyDocDB
object MyDocDB extends DocDB[Out] {
def searchFor[I] (docs: Iterable[I], queryStrategy: QueryStrategy[I, DocDB[_]]) = List()
}
// MyQueryStrategy for In and MyDocDB
implicit object MyQueryStrategy extends QueryStrategy[In, MyDocDB.type]

implicit def listExt[I] (items: Iterable[I]) = new {
def findAt[O, F <: DocDB[O]](docDB: F) = new {
def apply(implicit queryStrategy: QueryStrategy[I, F]): Iterable[(I,O)] = {
docDB.searchFor[I](items, queryStrategy)
}
}
}

我真正想要的是能够写作

val out1: Iterable[(In, Out)] = List[In]() findAt MyDocDB

通过使用查询策略 MyQueryStrategy(通过隐式定义为此输入类型和 DocDB 的默认值)在 MyDocDB 中为我的输入文档找到相应的文档。

不幸的是,Scala 编译在该行有问题。它声称它无法推断类型:

error: inferred type arguments [Nothing,test.StackOverflow.MyDocDB.type] do not conform to method findAt's type parameter bounds [O,F <: test.StackOverflow.DocDB[O]]
val out1: Iterable[(In, Out)] = List[In]() findAt MyDocDB

它以某种方式推断出 Nothing 而不是 Out。我如何在不明确告诉编译器它应该假定 OOut 类型的情况下解决这个问题?我的意思是,以下工作但不会导致简洁的 DSL:

val out2: Iterable[(In, Out)] = List[In]().findAt[Out, MyDocDB.type](MyDocDB).apply(MyQueryStrategy)

有什么建议吗?

编辑:

非常感谢您的回答。我最终采用了 paradigmatic 的解决方案,因为它允许查询策略可以针对我在项目中实际需要的特定 DocDB。除了范例的解决方案之外,我还用

替换了 listExt 函数
implicit def listExt[I] (items: Iterable[I]) = new {
def findAt[F <: DocDB](docDB: F)(implicit queryStrategy: QueryStrategy[I, F]): Iterable[(I,F#O)] = {
docDB.searchFor[I](items, queryStrategy)
}
}

这样我就可以省略 apply 方法和隐式 QueryStrategy:

val out1: Iterable [(In,Out)] = List[In]() findAt MyDocDB

再次感谢。

最佳答案

我通过在 DocDB 中将 O 转换为抽象类型并使用类型投影取得了一些成功:

trait DocDB {
type O
def searchFor[I](
docs: Iterable[I],
queryStrategy: QueryStrategy[I, DocDB]
): Iterable[(I,O)]
}

trait QueryStrategy[I, +F <: DocDB]

class In // class of input documents
class Out // class of output documents

object MyDocDB extends DocDB {

type O = Out
def searchFor[I](
docs: Iterable[I],
queryStrategy: QueryStrategy[I, DocDB]
) = List()
}

implicit object MyQueryStrategy extends QueryStrategy[In, MyDocDB.type]

implicit def listExt[I] (items: Iterable[I]) = new {
def findAt[F <: DocDB](docDB: F) = new {
def apply(implicit queryStrategy: QueryStrategy[I, F]):
Iterable[(I,F#O)] = {
docDB.searchFor[I](items, queryStrategy)
}
}
}

它似乎有效:

scala> val out1: Iterable [(In,Out)] = List[In]() findAt MyDocDB apply
out1: Iterable[(In, Out)] = List()

关于Scala 编译器无法推断类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7050935/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com