3

我有以下玩具功能:

def test[T](x: Option[List[Option[T]]])
{
    for (a <- x; b <- a; c <- b) println(c)
    println("----------")
}

我如何概括上述函数,使其也适用于Option[Option[Option[T]]]or或andList[List[List[T]]]的任何其他组合?OptionList

以下尝试显然不起作用,因为类型不是类型构造函数:

def test2[Q,R,S,T](x: Q[R[S[T]]])

在 C++ 中,我可能会为此目的使用模板模板。Scala有类似的东西吗?

4

2 回答 2

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("----------")
}
于 2012-04-11T14:28:24.630 回答
1

Option 和 List 都实现了 for 循环使用的 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。

于 2012-04-11T14:37:47.987 回答