我有以下玩具功能:
def test[T](x: Option[List[Option[T]]])
{
for (a <- x; b <- a; c <- b) println(c)
println("----------")
}
如何概括上述功能,以便它也适用于Option[Option[Option[T]]]
或List[List[List[T]]]
或Option
和List
的任何其他组合?
以下尝试显然不起作用,因为类型不是类型构造函数:
def test2[Q,R,S,T](x: Q[R[S[T]]])
在C ++中,我可能会使用模板模板来实现此目的。 Scala有类似的东西吗?
答案 0 :(得分:4)
您可以使用Scalaz吗?如果是这样,使用Each
类型类很容易:
import scalaz._, Scalaz._
def test[Q[_]: Each, R[_]: Each, S[_]: Each, T](x: Q[R[S[T]]]) {
for (a <- x; b <- a; c <- b) println(c)
println("----------")
}
答案 1 :(得分:1)
Option和List都实现了for-loop使用的foreach方法,但没有一个普通的超类型。但是,结构类型可以通过将我们想要的方法声明为类型来实现。
type E[V] = {def foreach[U](f: (V) => U)}
def test2[Q[R] <: E[R],R[S] <: E[S],S[T] <: E[T],T](x: Q[R[S[T]]]) {
for (a <- x; b <- a; c <- b) println(c)
println("----------")
}
示例:
scala> test2(List(List(List(8))))
8
scala> test2(Some(List(Some(8))))
8
如果您将for循环更改为使用yield,则需要更改E以实现flatmap和map-methods而不是foreach。