为什么理解扩展为`withFilter`

Pye*_*ras 6 scala for-comprehension scalding

我正在研究用于关系(类似SQL)运算符的DSL.我有一个Rep[Table]类型.apply: ((Symbol, ...)) => Obj,返回一个Obj定义.flatMap: T1 => T2.map: T1 => T3函数的对象的方法.由于类型Rep[Table]对基础表的模式一无所知,因此该apply方法就像投影一样 - 仅投影参数元组中指定的字段(很像无类型的烫印api).现在type T1是一个"类似元组",它的长度受到一些无形魔法约束到投影元组的长度,但是否则元组元素的类型由api用户决定,所以代码就像

val a = loadTable(...)
val res = a(('x, 'y)).map { (t: Row2[Int, Int]) =>
  (1, t(0))
}
Run Code Online (Sandbox Code Playgroud)

要么

val res = a(('x, 'y)).map { (t: Row2[String, String]) =>
  (1, t(0))
}
Run Code Online (Sandbox Code Playgroud)

工作良好.请注意,必须显式指定map/ flatMapfunction 的参数类型.但是,当我尝试用它来理解时

val a = loadTable(...)
val b = loadTable(...)
val c = loadTable(...)

val res = for {
  as: Row2[Int, Int] <- a(('ax, 'ay))
  bs: Row2[Int, Int] <- b(('bx, 'by))
  cs: Row2[Int, Int] <- c(('cx, 'cy))
} yield (as(0), as(1), bs(0), bs(1), cs(0), cs(1))
Run Code Online (Sandbox Code Playgroud)

抱怨缺乏withFilter经营者.添加一个.withFilter: T1 => Boolean不会削减它 - 它然后抱怨"缺少扩展函数的参数类型",因为T1某些类型参数化.只有添加.withFilter: Row[Int, Int] => Boolean使它工作,但显然不是我想要的.

我的问题是:为什么withFilter首先调用get,如何将它与我的参数化元组类型一起使用T1


编辑 最后,我选择了一个.withFilter: NothingLike => BoolLike用于简单检查的noop,_.isInstanceOf[T1]并且.filter: T1 => BoolLike在一般情况下更受限制.

gzm*_*zm0 14

不幸的是,当你期望基于lambda的参数类型的类型推断时,你不能使用for-comprehension.

实际上,在您的示例中,as: Row2[Int, Int]被解释为模式匹配:

val res = for {
  as: Row2[Int, Int] <- a(('ax, 'ay))
} yield (...)
Run Code Online (Sandbox Code Playgroud)

转换为:

a(('ax, 'ay)).withFilter(_.isInstanceOf[Row2[Int, Int]]).map(...)
Run Code Online (Sandbox Code Playgroud)

理解中的模式匹配非常有用:

val names = for {
  ("name", name) <- keyValPairs
} yield name
Run Code Online (Sandbox Code Playgroud)

但权衡的是,你无法明确指定lambda的参数类型.