【发布时间】:2021-03-26 09:33:16
【问题描述】:
我正在尝试创建一个函数,该函数采用更高种类的类型元组并将函数应用于更高种类的类型。
在下面的示例中,有一个trait Get[A],它是我们的高级类型。还有一个 Get 的元组:(Get[String],Get[Int]) 以及来自(String,Int) => Person 的函数。
Scala-3 有一个称为 InverseMap 的 Match-Type,它将类型 (Get[String], Get[Int]) 转换为本质上的类型 (String,Int)。
所以最终目标是编写一个函数,它可以接受一个具有任意数量Get[_] 类型的元组和一个输入与 InserveMap 类型匹配的函数,最后返回一个 Get[_],其中包装的类型是函数。
我试图在下面创建一个名为 genericF 的函数来显示所需的行为,尽管它可能不正确——但我认为它至少显示了正确的意图。
case class Person(name: String, age: Int)
trait Get[A] {
def get: A
}
case class Put[A](get: A) extends Get[A]
val t: (Get[String], Get[Int]) = (Put("Bob"), Put(42))
val fPerson: (String,Int) => Person = Person.apply _
def genericF[T<:Tuple,I<:Tuple.InverseMap[T,Get],B](f: I => B, t: T): Get[B] = ???
val person: Get[Person] = genericF(fPerson, t)
我在这里设置了一个 Scastie:https://scastie.scala-lang.org/OleTraveler/QIyNHPLHQIKPv0lgsYbujA/23
【问题讨论】:
-
我不认为
Get是 HKT - 它有一个类型参数,但该参数本身不是类型构造函数 -
好吧,首先,
fPerson不接受 2 元组,它接受两个参数,所以我猜你想要另一对括号 -
我相信
Get是一阶类型,因为您可以通过将类型传递给类型参数来创建正确的类型,例如Get[String]是正确的类型。 -
在 Scala-3 中,元组是具有 0 个或更多元素的元组的通用表示,因此不需要更多的括号。我希望创建 genericF 能够处理任何大小的元组,而不仅仅是示例中显示的 2 的大小。
-
@TravisStevens 方法参数中不需要括号:您可以调用
extract(Put("Bob"), Put(42))或extract((Put("Bob"), Put(42)))。但是(String,Int) => Person和((String,Int)) => Person类型是不同的。
标签: scala tuples dotty scala-3