试图找出正确的类型
Attempting to figure out the correct type for this
抱歉,这将是一个有点菜鸟的问题。我有一个来自 slick 库的对象,它的类型如下:
Query[(Rep[String], Rep[String]), (String, String), Seq]
我正在尝试编写一个接受查询作为参数的函数,尽管其中的序列长度不确定 - 即,它同样可以是:
Query[(Rep[String], Rep[String], Rep[String]), (String, String, String), Seq]
因此前两个组件具有三个元素而不是两个。我不知道这是怎么做到的。我尝试了各种错误的排列,例如 Query[Product[Rep[String]], Product[String], Seq]
,但都无济于事,甚至我认为仅使用 Any
的核选项也不起作用。我的错误信息是
[error] found : Option[slick.driver.H2Driver.api.Query[(slick.driver.H2Driver.api.Rep[String], slick.driver.H2Driver.api.Rep[String]),(String, St
ring),Seq]]
[error] (which expands to) Option[slick.lifted.Query[(slick.lifted.Rep[String], slick.lifted.Rep[String]),(String, String),Seq]]
[error] required: Option[slick.driver.H2Driver.api.Rep[scala.concurrent.Future[List[String]]]]
[error] (which expands to) Option[slick.lifted.Rep[scala.concurrent.Future[List[String]]]]
[error] ReturnFunctions.completeQuery(db, query, serialize_and_send)
我认为我无法解决这个问题可能反映出对 scala、一般强类型语言以及可能对整个计算缺乏基本的理解。在尝试将其传递给函数之前,我是否应该将此查询解析为更明确的形式?我还怀疑我没有正确解释原始类型——括号在这种情况下是什么意思? Query 是否期望接收三组参数,一个接一个,就像你执行 fn(arg1)(arg2)(arg3) = ...?
非常感谢任何解决这个令人不安的困境的帮助。
I also suspect I'm not interpreting the original type correctly - what do the parentheses mean in this context?
您看到的是一个合理的高级区域,但让我们尝试提供帮助。
Query
类型始终具有三个类型参数。您会看到它们写成 Query[M, U, C]
。
第一个参数,M
,是一个元组。这就是括号在这种情况下的意思。
在您的第一个示例中,M
是两个元素的元组;第二个是三个。第二个参数 U
也存在同样的情况。 Essential Slick.
中有更多详细信息
在 Scala 中,您可以使用泛型参数。这意味着您可以按照以下方式说一些话:
def foo[M, U, C[_]](q: Query[M,U,C]) = ???
我们定义了一个方法:
- 三个类型参数;和
- 采用具有这些类型的查询参数。
我们没有说任何关于 M
、U
的事情,也没有说太多关于 C
的事情(除了它是一个以类型作为参数的类型)。这意味着我们对它们无能为力,但您可能不需要。
query enrichment in Slick 上的 post 给出了一个可能有用的更长(相关)示例。
正如 Dmytro 所建议的,更好的方法是创建一个具体示例,说明您希望实现的目标并以此为基础开展工作。
考虑Query
类型构造函数的形状
Query[+E, U, C[_]]
我们说 Query
是类型 constructor 因为它根据给定的类型参数 E
、U
和 U
构造了一个具体类型C[_]
,类似于函数如何根据给定的函数参数构造具体值。
现在让我们尝试解构具体类型
Query[(Rep[String], Rep[String]), (String, String), Seq]
进入其组成类型参数。我们有
E = (Rep[String], Rep[String])
U = (String, String)
C[_] = Seq
注意 (A, B)
只是 Tuple2[A, B]
的语法糖,因此
E = (Rep[String], Rep[String]) = Tuple2[Rep[String], Rep[String]]
U = (String, String) = Tuple2[String, String]
C[_] = Seq = Seq
您可能想知道 C[_]
中的下划线。这指定类型参数 C
必须是类型构造函数而不是具体类型。例如 Seq
是类型构造函数,而 Seq[Int]
不是。此外,您可能想知道 +E
中的 +
。这指定了参数化类型的继承关系,或者说变体,例如,它指定Seq[Dog]
是否是Seq[Animal]
的子类型。
最后让我们详细地写出最终的具体类型
Query[Tuple2[Rep[String], Rep[String]], Tuple2[String, String], Seq]
抱歉,这将是一个有点菜鸟的问题。我有一个来自 slick 库的对象,它的类型如下:
Query[(Rep[String], Rep[String]), (String, String), Seq]
我正在尝试编写一个接受查询作为参数的函数,尽管其中的序列长度不确定 - 即,它同样可以是:
Query[(Rep[String], Rep[String], Rep[String]), (String, String, String), Seq]
因此前两个组件具有三个元素而不是两个。我不知道这是怎么做到的。我尝试了各种错误的排列,例如 Query[Product[Rep[String]], Product[String], Seq]
,但都无济于事,甚至我认为仅使用 Any
的核选项也不起作用。我的错误信息是
[error] found : Option[slick.driver.H2Driver.api.Query[(slick.driver.H2Driver.api.Rep[String], slick.driver.H2Driver.api.Rep[String]),(String, St
ring),Seq]]
[error] (which expands to) Option[slick.lifted.Query[(slick.lifted.Rep[String], slick.lifted.Rep[String]),(String, String),Seq]]
[error] required: Option[slick.driver.H2Driver.api.Rep[scala.concurrent.Future[List[String]]]]
[error] (which expands to) Option[slick.lifted.Rep[scala.concurrent.Future[List[String]]]]
[error] ReturnFunctions.completeQuery(db, query, serialize_and_send)
我认为我无法解决这个问题可能反映出对 scala、一般强类型语言以及可能对整个计算缺乏基本的理解。在尝试将其传递给函数之前,我是否应该将此查询解析为更明确的形式?我还怀疑我没有正确解释原始类型——括号在这种情况下是什么意思? Query 是否期望接收三组参数,一个接一个,就像你执行 fn(arg1)(arg2)(arg3) = ...?
非常感谢任何解决这个令人不安的困境的帮助。
I also suspect I'm not interpreting the original type correctly - what do the parentheses mean in this context?
您看到的是一个合理的高级区域,但让我们尝试提供帮助。
Query
类型始终具有三个类型参数。您会看到它们写成 Query[M, U, C]
。
第一个参数,M
,是一个元组。这就是括号在这种情况下的意思。
在您的第一个示例中,M
是两个元素的元组;第二个是三个。第二个参数 U
也存在同样的情况。 Essential Slick.
在 Scala 中,您可以使用泛型参数。这意味着您可以按照以下方式说一些话:
def foo[M, U, C[_]](q: Query[M,U,C]) = ???
我们定义了一个方法:
- 三个类型参数;和
- 采用具有这些类型的查询参数。
我们没有说任何关于 M
、U
的事情,也没有说太多关于 C
的事情(除了它是一个以类型作为参数的类型)。这意味着我们对它们无能为力,但您可能不需要。
query enrichment in Slick 上的 post 给出了一个可能有用的更长(相关)示例。
正如 Dmytro 所建议的,更好的方法是创建一个具体示例,说明您希望实现的目标并以此为基础开展工作。
考虑Query
类型构造函数的形状
Query[+E, U, C[_]]
我们说 Query
是类型 constructor 因为它根据给定的类型参数 E
、U
和 U
构造了一个具体类型C[_]
,类似于函数如何根据给定的函数参数构造具体值。
现在让我们尝试解构具体类型
Query[(Rep[String], Rep[String]), (String, String), Seq]
进入其组成类型参数。我们有
E = (Rep[String], Rep[String])
U = (String, String)
C[_] = Seq
注意 (A, B)
只是 Tuple2[A, B]
的语法糖,因此
E = (Rep[String], Rep[String]) = Tuple2[Rep[String], Rep[String]]
U = (String, String) = Tuple2[String, String]
C[_] = Seq = Seq
您可能想知道 C[_]
中的下划线。这指定类型参数 C
必须是类型构造函数而不是具体类型。例如 Seq
是类型构造函数,而 Seq[Int]
不是。此外,您可能想知道 +E
中的 +
。这指定了参数化类型的继承关系,或者说变体,例如,它指定Seq[Dog]
是否是Seq[Animal]
的子类型。
最后让我们详细地写出最终的具体类型
Query[Tuple2[Rep[String], Rep[String]], Tuple2[String, String], Seq]