具有参数的方法的Scala Typeclass

时间:2019-02-24 18:38:59

标签: scala typeclass

我试图通过类型类向Array[T]添加“乘标量相乘”之类的方法,以模仿numpy功能。我看过an example,它可以工作,并且向Array[T]添加了不带参数的“ show”方法。但是,就我而言,我发现我无法添加带有参数的方法,例如array.*(2.0)

使用Scala 2.12.6。

如何使此代码起作用?

package numpy

trait BehaveLikeNumpy[T] {
  def *(a: Array[T], x: T): Array[T]
}

object BehaveLikeNumpyInstances {

  def apply[T](implicit bln: BehaveLikeNumpy[T]): BehaveLikeNumpy[T] = bln

  object ops {
    def *[T: BehaveLikeNumpy](a: Array[T], x: T): Array[T] = BehaveLikeNumpyInstances[T].*(a, x)

    implicit class BehaveLikeNumpyOps[T: BehaveLikeNumpy](a: Array[T]) {
      def *(x: T) = BehaveLikeNumpyInstances[T].*(a, x)
    }
  }

  implicit val arrayTimes_Double = (a: Array[Double], x: Double) => a.map(y => y * x)
}

package some.pkg
import numpy.BehaveLikeNumpyInstances
import numpy.BehaveLikeNumpyInstances.ops._

val aaa: Array[Double] = (0 until 5).toArray.map(_.toDouble)
aaa.show // Works. See https://blog.scalac.io/2017/04/19/typeclasses-in-scala.html
val s1 = aaa.*(2.0)// Error: value * is not a member of Array[Double]
val s2 = aaa * 2.0 // Error: value * is not a member of Array[Double]

1 个答案:

答案 0 :(得分:2)

首先,您丢失了类型(用于将lambda转换为SAM特性)

implicit val arrayTimes_Double: BehaveLikeNumpy[Double] = 
  (a: Array[Double], x: Double) => a.map(y => y * x)

第二次您失去了下划线

import numpy.BehaveLikeNumpyInstances._