将函数应用于Scala中具有泛型类型的对象

时间:2016-06-02 06:27:38

标签: scala generics

我有这段代码

import scala.reflect.ClassTag

case class Data[T: ClassTag](list: List[T]) {

}

trait Transformation {
  type T
  type U
  def transform(data: Data[T]) : Data[U]
}

class FromInt2String extends Transformation {
  override type T = Int
  override type U = String

  override def transform(data: Data[T]) = new Data(List("1", "2", "3"))
}

class FromString2Int extends Transformation {
  override type T = String
  override type U = Int

  override def transform(data: Data[T]) = new Data(List(1, 2, 3))
}

object Test extends App {
  override def main(args: Array[String]) {
    val data = new Data(List(1, 2, 3))

    val int2String = new FromInt2String()
    val data2 = int2String.transform(data)

    val string2Int = new FromString2Int()
    val data3 = string2Int.transform(data2)


    val transformations = List(int2String, string2Int)
    val data4 = transformations.foldLeft(data)((data, transformation) => {
      transformation.transform(data)
    })
  }
}

问题出在foldLeft方法中。我无法做到这一点,因为类型不兼容,但我需要在初始对象数据中应用所有变换

任何想法怎么做?

谢谢

1 个答案:

答案 0 :(得分:0)

我已使用shapeless和此post

解决了这个问题
import scala.reflect.ClassTag
import shapeless._

object andThen extends Poly2 {
  implicit def functions[A, B, C] = at[A => B, B => C](_ andThen _)
}

case class Data[T: ClassTag](list: List[T]) {

}

trait Transformation {
  type T
  type U
  def transform(data: Data[T]) : Data[U]
}

class FromInt2String extends Transformation {
  override type T = Int
  override type U = String

  override def transform(data: Data[T]) = new Data(List("1s", "2s", "3s"))
}

class FromString2Int extends Transformation {
  override type T = String
  override type U = Int

  override def transform(data: Data[T]) = new Data(List(4, 5, 6))
}

object Test extends App {
  override def main(args: Array[String]) {
    val data = new Data(List(1, 2, 3))
    println(data)

    val int2String = new FromInt2String()
    val data2 = int2String.transform(data)
    println(data2)

    val string2Int = new FromString2Int()
    val data3 = string2Int.transform(data2)
    println(data3)


    val transformations = int2String.transform _ :: string2Int.transform _ :: HNil
    val functions = transformations.reduceLeft(andThen)
    val data4 = functions(data)
    println(data4)
  }
}

感谢所有帮助我的人