Aradığınız işlev genellikle zipWith
olarak adlandırılır. Maalesef standart kütüphanelerde sağlanan, ancak yazmak için oldukça kolay değil:
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
}
Bu sadece bir kez üzerinden geçer, yineleyiciler üzerinde zip
ve map
için uygulamalar tamamen tembel olduğundan.
Ancak neden Iterable
durur? Bunun daha genel bir formu var. Bu şekilde sıkıştırılabilen tüm veri yapıları için bir arayüz belirtebiliriz.
trait Zip[F[_]] {
def zipWith[A,B,C](f: (A,B) => C, a: F[A], b: F[B]): F[C]
}
Örneğin, işlevlerini zip: Bu tip daha da genel ifadesi olmalı çıkıyor
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))
}
. Bu arayüz bir uygulanmasına izin genel yazın yapıcıları olarak applicative functors
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]
}
zipWith bir uygulama daha sonra olduğu gibi bu:
Bu, herhangi bir Arity işlevleriyle genelleştirir
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)
:
m.ap(m.ap(m.ap(m.map(f,a), b), c), d)
Scalaz kitaplığı, standart kitaplıktaki birçok veri yapısı için Uygulamalı örnekler sağlar. Ayrıca, ap
için uygun sözdizimi sağlanmıştır. Scalaz'da, bu işlev <*>
:
def zipWith[F[_]:Applicative,A,B,C](f: A => B => C, a: F[A], b: F[B]) =
(a map f) <*> b
olarak adlandırılırsa, zip() işlevi çalışmıyorsa, farklı bir şekilde ne yapmanız gerekir? –
oğlu ... zip. Tamamdır! Bunu düşünmemiştim bile. Neden yayınlamıyorsun ki, bunu yapabilirim. – wheaties
Ben cevaplamak için @Mike'ı bırakacağım, ancak 'list1 zip list2' ve ayrıca' (list1, list2) .zipli 'yapabilirsin. İkincisi, sadece Scala 2.8, geçici bir koleksiyon oluşturmaz. Ayrıca, geçici koleksiyonlar oluşturmaktan kaçınmak için sırasıyla Scala 2.8 ve 2.7 üzerinde 'list1.view zip list2' veya' list1.projection zip list2' yapabilirsiniz. –