如何将函数应用于矩阵?

时间:2017-07-23 07:40:09

标签: scala matrix applicative scala-cats

这是我之前question

的后续内容

现在我知道catsApply提供了Vector的实例。所以我可以写:

import cats.implicits._

scala> val f: Int => Int = _ + 2
f: Int => Int = <function1>

scala> Vector(f) ap Vector(1, 2, 3)
res18: scala.collection.immutable.Vector[Int] = Vector(3, 4, 5)

现在我想知道如何将f应用于定义为Vector[Vector[Int]的矩阵的所有元素。 cats是否为矩阵提供了Apply个实例?

1 个答案:

答案 0 :(得分:1)

要在ap上使用Vector[Vector[Int]],您需要将f提升到Vector[Vector[A => B]]。一种可能的方法是:

import cats.Apply
import cats.implicits._

val f: Int => Int = _ + 2
val vectorOfVectors = Apply[Vector] compose Apply[Vector]
val vec = Vector(Vector(1,2), Vector(3,4))
val res: Vector[Vector[Int]] = vectorOfVectors.ap(Vector(Vector(f)))(vec)

收率:

Vector(3, 4)
Vector(5, 6)

IMO使用Nested的更好方式:

kind-projector中使用build.sbt

addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.4")

然后:

import cats.Functor
import cats.data.Nested
import cats.implicits._

val f: Int => Int = _ + 2
val vec = Vector(Vector(1,2), Vector(3,4))
val nested: Nested[Vector, Vector, Int] = Nested(vec)
val res: Nested[Vector, Vector, Int] = Functor[Nested[Vector, Vector, ?]].map(nested)(f)
val result: Vector[Vector[Int]] = res.value

请注意,使用Nested表示我们可以根据f申请,而不会解除任何提升。