whe*_*ies 9 python iterable scala applicative
我知道Scala的列表有一个带签名的map实现和带签名(f: (A) => B):List[B]的foreach实现,(f: (A) => Unit):Unit但我正在寻找接受多个iterables的东西,就像Python map接受多个iterables一样.
我正在寻找具有特征(f: (A,B) => C, Iterable[A], Iterable[B] ):Iterable[C]或同等特征的东西.是否存在存在这样的库或类似的类似方法?
编辑:
如下所示,我可以做到
val output = myList zip( otherList ) map( x => x(0) + x(1) )
Run Code Online (Sandbox Code Playgroud)
但这会在两个步骤之间创建一个临时列表.如果评论员会发帖,我可以赞成他(提示,提示),但还有另一种方式吗?
Eas*_*sun 12
在scala 2.8中,在Tuple2和Tuple3中有一个名为zipped的方法,它可以避免创建临时集合.以下是一些示例用例:
Welcome to Scala version 2.8.0.r21561-b20100414020114 (Java HotSpot(TM) Client VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val xs = 0 to 9
xs: scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> val ys = List.range(0,10)
ys: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> val zs = Array.range(0,10)
zs: Array[Int] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> (xs,ys).zipped.map{ _+_ }
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4, 6, 8, 10, 12, 14, 16, 18)
scala> (zs,ys,xs).zipped.map{ _+_+_ }
res2: Array[Int] = Array(0, 3, 6, 9, 12, 15, 18, 21, 24, 27)
scala>
Run Code Online (Sandbox Code Playgroud)
Tuple2和Tuple3都有一个zip方法.xs.zip(ys)与(xs,ys).zip相同
注意:(xs,ys).zip和(xs,ys).zip也存在一些不足,请确保xs不能是INFINITE Stream.有关更多信息,请转到Ticket#2634.我几天前在nabble.com上发了一篇帖子,显示了我对如何修理这张票的看法.
Apo*_*isp 11
您正在寻找的功能通常被称为zipWith.遗憾的是,它没有在标准库中提供,但它很容易编写:
def zipWith[A,B,C](f: (A,B) => C, a: Iterable[A], b: Iterable[B]) =
new Iterable[C] {
def elements = (a.elements zip b.elements) map f.tupled
}
Run Code Online (Sandbox Code Playgroud)
这将只遍历一次,因为迭代器的实现zip和map完全是惰性的.
但为什么要停下来Iterable?这有一个更普遍的形式.我们可以为所有可以这种方式压缩的数据结构声明一个接口.
trait Zip[F[_]] {
def zipWith[A,B,C](f: (A,B) => C, a: F[A], b: F[B]): F[C]
}
Run Code Online (Sandbox Code Playgroud)
例如,我们可以压缩功能:
trait Reader[A] {
type Read[B] = (A => B)
}
def readerZip[T] = new Zip[Reader[T]#Read] {
def zipWith[A,B,C](f: (A,B) => C, a: T => A, b: T => B): T => C =
(t: T) => f(a(t),b(t))
}
Run Code Online (Sandbox Code Playgroud)
事实证明这种类型更为一般.通常,允许实现此接口的类型构造函数是applicative functor
trait Applicative[F[_]] {
def pure[A](a: A): F[A]
def map[A,B](f: A => B, a: F[A]): F[B]
def ap[A,B](f: F[A => B], a: F[A]): F[B]
}
Run Code Online (Sandbox Code Playgroud)
zipWith的实现就是这样:
def zipWith[F[_],A,B,C](f: A => B => C, a: F[A], b: F[B])
(implicit m: Applicative[F]) =
m.ap(m.map(f,a), b)
Run Code Online (Sandbox Code Playgroud)
这概括为任何arity的功能:
m.ap(m.ap(m.ap(m.map(f,a), b), c), d)
Run Code Online (Sandbox Code Playgroud)
所述Scalaz库提供应用型实例为在标准库大量的数据结构.此外,还提供了方便的语法ap.在Scalaz中,这个函数被称为<*>:
def zipWith[F[_]:Applicative,A,B,C](f: A => B => C, a: F[A], b: F[B]) =
(a map f) <*> b
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2478 次 |
| 最近记录: |