抽象类型构造函数

时间:2012-04-11 13:54:18

标签: scala generics types abstraction type-parameter

我有以下玩具功能:

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]]]OptionList的任何其他组合?

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

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

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

2 个答案:

答案 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。