用于返回各种数字类型的Scala方法类型参数规范

时间:2015-03-29 14:02:42

标签: scala

我试图了解scala类型参数,并且在确定如何进行转换时遇到一些困难。

假设我正在建模tic-tac-toe:

sealed trait Side {

  def toChar   : Char
  def toInt    : Int
  def toDouble : Double = toInt.toDouble

}//end trait Side

case object X extends Side {
  override val toChar = 'X'
  override val toInt = -1
}//end case object X extends Side

case object O extends Side {
  override val toChar = 'O'
  override val toInt = 1
}//end case object O extends Side

case object EMPTY extends Side {
  override val toChar = '*'
  override val toInt = 0
}

然后我以一种自然代表游戏的方式模拟一个tic tac板,也可以转换为一个对机器学习技术有用的数字数组。

class Board(val rows : Int = 3, 
            val cols : Int = 3, 
            val repr : Array[Array[Side]] = Array.ofDim[Side](3,3)) {

  def flatten : Array[Side] = repr.flatten

  /**
   * Converts this board into a 1-D numeric array.  This is likely the 
   * incorrect method signature.
   */
  def flattenNumeric[T] : Array[T] = ???

}

我的问题是:如何替换???

我希望能够调用表格

val board = new Board

board.flattenNumeric[Int] //returns Array(0, 0, 0, 0, 0, 0, 0, 0, 0)
board.flattenNumeric[Double] //returns Array(0.0, 0.0, ...)

提前感谢您的协助。

1 个答案:

答案 0 :(得分:1)

如果您只需要使用两种类型参数,我建议您只编写单独的flattenIntflattenDouble方法 - 它更简单,更清晰。但是,这不是你问题的答案,所以如果你真的希望这是通用的,那么标准的Scala方法就是使用这样的type class

class Board(val rows: Int = 3, 
            val cols: Int = 3, 
            val repr: Array[Array[Side]] = Array.ofDim[Side](3,3)) {

  def flatten: Array[Side] = repr.flatten

  trait FromSide[A] {
    def apply(side: Side): A
  }

  object FromSide {
    implicit object intFromSide extends FromSide[Int] {
      def apply(side: Side) = side.toInt
    }

    implicit object doubleFromSide extends FromSide[Double] {
      def apply(side: Side) = side.toDouble
    }

    implicit object charFromSide extends FromSide[Char] {
      def apply(side: Side) = side.toChar
    }
  }

  /**
   * Converts this board into a 1-D numeric array.  This is likely the 
   * incorrect method signature.
   */
  def flattenNumeric[T: FromSide: Manifest]: Array[T] =
    flatten.map(implicitly[FromSide[T]].apply)
}

现在,例如board.flattenNumeric[Int]会编译,但flattenNumeric[String]会赢。

请注意Manifest部分只是因为您正在使用Array而必需 - 如果您切换到Scala自己的收藏类型,则您不需要它。< / p>

通过使用清单或类型标记也可以做到这一点,但这是使程序成为可怕的运行时错误的快速方法。