【问题标题】:implicit Impl method for collections in scala breezescala微风中集合的隐式Impl方法
【发布时间】:2016-02-23 07:32:24
【问题描述】:

我在 SortedMap[Int, Double] 上有一个类型别名,我想有一个隐式允许我将 SortedMap 传递给微风中的一些内置函数,特别是 breeze.stats._ 函数 @987654325 @ 和stddev

这是一个没有隐式的工作示例:

package com.soquestion

import breeze.linalg._
import breeze.stats._
import scala.collection.SortedMap
import scala.language.implicitConversions

object proof {
  type Series = SortedMap[Int, Double]

  def example: Double = {
    val s: Series = SortedMap(1 -> 9.0, 2 -> 2.0, 3 -> 5.0, 4 -> 4.0, 5 -> 12.0, 6 -> 7.0, 7 -> 8.0, 8 -> 11.0, 9 -> 9.0, 10 -> 3.0, 11 -> 7.0, 12 -> 4.0, 13 -> 12.0, 14 -> 5.0, 15 -> 4.0, 16 -> 10.0, 17 -> 9.0, 18 -> 6.0, 19 -> 9.0, 20 -> 4.0)

    stddev(s.values)
  }
}

sbt console运行

scala> com.soquestion.proof.example
res0: Double = 3.0607876523260447

我想要的是不必指定.values,只需调用stddev(s)variance(s)

这是我尝试过的

package com.soquestion

import breeze.linalg._
import breeze.stats._
import scala.collection.SortedMap
import scala.language.implicitConversions

object proof {
    // Implicitly convert the SortedMap, or any map, to a DenseVector[Double]
  implicit def series2DenseVector(s: Traversable[(Int, Double)]): DenseVector[Double] = {
    DenseVector(s.map(_._2).toArray)
  }
  type Series = SortedMap[Int, Double]

  def example: Double = {
    val s: Series = SortedMap(1 -> 9.0, 2 -> 2.0, 3 -> 5.0, 4 -> 4.0, 5 -> 12.0, 6 -> 7.0, 7 -> 8.0, 8 -> 11.0, 9 -> 9.0, 10 -> 3.0, 11 -> 7.0, 12 -> 4.0, 13 -> 12.0, 14 -> 5.0, 15 -> 4.0, 16 -> 10.0, 17 -> 9.0, 18 -> 6.0, 19 -> 9.0, 20 -> 4.0)

    stddev(s) // <--- compiler error here
  }
}

但我得到一个编译器错误

could not find implicit value for parameter impl: breeze.stats.stddev.Impl[com.soquestion.proof.Series,VR]

浏览微风文档,我无法找到一个很好的例子来说明我需要提供什么隐式。理想情况下,我想创建一个隐式,允许我同时调用 stdevvariance 而没有多个隐式。

我确实看到了Scala Breeze DenseVector Implicit failure 的问题,但我不明白它会如何应用于这种情况。

完整格式的答案基于以下@dlwh 的答案,以防将来有人需要它

package com.soquestion

import breeze.linalg.support._
import breeze.linalg.support.CanTraverseValues._
import breeze.stats._
import scala.annotation.tailrec
import scala.collection.SortedMap
import scala.language.implicitConversions

object proof {
  type Series = SortedMap[Int, Double]

  def example: Double = {
    // ideally this implicit would go in a scope higher up so it could be
    // brought in wherever it's needed, but this works for a sample
    implicit object SeriesIter extends CanTraverseValues[Series, Double] {
      def isTraversableAgain(from: Series) = true
      def traverse(from: Series, fn: ValuesVisitor[Double]): Unit = {
        @tailrec def traverser(idx: Int, t: Array[Double]): Unit = {
          if (idx == 1) fn.visit(t.head)
          else {
            fn.visit(t.head)
            traverser(idx - 1, t.tail)
          }
        }
        val v: Array[Double] = from.values.toArray
        fn.zeros(0, 0d)
        traverser(v.size, v)
      }
    }

    val s: Series = SortedMap(1 -> 9.0, 2 -> 2.0, 3 -> 5.0, 4 -> 4.0, 5 -> 12.0, 6 -> 7.0, 7 -> 8.0, 8 -> 11.0, 9 -> 9.0, 10 -> 3.0, 11 -> 7.0, 12 -> 4.0, 13 -> 12.0, 14 -> 5.0, 15 -> 4.0, 16 -> 10.0, 17 -> 9.0, 18 -> 6.0, 19 -> 9.0, 20 -> 4.0)
    stddev(s)
  }
}

【问题讨论】:

  • 提出了一个更简单的实现的改变(实际上并没有仔细检查它,但我认为它是正确的)

标签: scala implicit scala-breeze


【解决方案1】:

文档可能会更好,我希望我可以使错误消息更有帮助。

如果您查看stddev's source,您会发现它需要variance.Impl 的实现,这需要meanAndVariance.Impl,可以为任何隐含CanTraverseValues[T, Double] 的类型提供。默认情况下,集合有一个 CanTraverseValues 隐含,但仅限于包含的类型,而不是 scala 的 Map 类型的值。 实现 CanTraverseValues 和 CanMapValues 将启用最轻松的 UFunc。

Scala 通常不会“链接”隐式,这就是您的 proof 示例不起作用的原因。

【讨论】:

  • 谢谢!我最终添加了以下内容,它很好地解决了隐式对象 mapLikeIter extends CanTraverseValues[Series, Double] { def isTraversableAgain(from: Series) = true def traverse(from: Series, fn: ValuesVisitor[Double]): Unit = { @ tailrec def traverser(idx: Int, t: Array[Double]): Unit = { if (idx == 1) fn.visit(t.head) else { fn.visit(t.head) traverser(idx - 1, t.tail) } } val v: Array[Double] = from.values.toArray fn.zeros(0, 0d) traverser(v.size, v) } }
猜你喜欢
  • 2014-02-09
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-04
  • 2011-06-08
相关资源
最近更新 更多