我想"打开"来自泛型类型的类型变量(不使用反射)。例如。在Option的情况下,目标是以下(或类似)代码编译:
implicitly[OptionUnwrapper[Option[Int]] =:= Int]
我设法提出以下解包器:
trait OptionUnwrapper[T] {
type Unwrap[_ <: Option[T]] = T
}
可以使用如下:
implicitly[OptionUnwrapper[Int]#Unwrap[Option[Int]] =:= Int]
这个解决方案的问题是,我必须在返回之前声明感兴趣的类型(在我的情况下为Int)。有没有办法找出这个参数,例如在通用函数中:
def foo[T](x: Option[T]) = x.isDefined
foo[Int](Some(1)) // function call with unnecessary type parameter,
foo(Some(1)) // since compiler infers Int automatically
更新1 - 使用案例
在我的实际用例中,我希望收到一个&#34;元组类型&#34;来自案例类。也就是说我有一个案例类
case class Person(name: (String, String), age: Int, hobbies: List[String])
我想要一些产生未应用人类型的东西。即。
type T = Tupled[Person] // T =:= Tuple3[Tuple2[String, String], Int, List[String]]
我试图通过使用Person.unapply函数的类型来实现这一点,这将是
Function1[Person, Option[Tuple3[...]]]
从这一点来看,计划将是&#34;解开&#34; Function1[_, Option[X]]
到X
答案 0 :(得分:1)
(请注意,我正在解决实际用例而不是原始的“解包类型变量”问题)
正如我在评论中所说,如果您愿意使用宏,我已经提供了一个适合该法案的宏:
How to do generic tuple -> case class conversion in Scala?
然后你可以这样做:
val PersonFactory = CaseClassFactory[Person]
type PersonTuple = PersonFactory.Tuple
但是考虑到你也准备好为每个案例类提供一些样板文件,你也可以选择一个无宏的解决方案:
implicit class TupleTypeProvider[O,T](unapply: O => Option[T]) { type Tuple = T }
def tupleTypeProvider[O,T](implicit p: TupleTypeProvider[O,T]) = p
// Usage
case class Person(name: (String, String), age: Int, hobbies: List[String])
val personTupleInfo = tupleTypeProvider(Person.unapply _)
type PersonTuple = personTupleInfo.Tuple
// Let's check:
implicitly[PersonTuple =:= Tuple3[Tuple2[String, String], Int, List[String]]]
或类似地:
implicit class TupleTypeProvider[O,T](tupled: T => O) { type Tuple = T }
def tupleTypeProvider[O,T](implicit p: TupleTypeProvider[O,T]) = p
// Usage
case class Person(name: (String, String), age: Int, hobbies: List[String])
val personTupleInfo = tupleTypeProvider((Person.apply _).tupled)
type PersonTuple = personTupleInfo.Tuple
// Let's check:
implicitly[PersonTuple =:= Tuple3[Tuple2[String, String], Int, List[String]]]