您无法使用严格列表来做到这一点,因此请使用惰性列表,即流。你必须定义Applicative[Stream]
实例如下图。 (您可以在 Haskell 标准库中以 ZipList 名称找到它。)
scala> val s1 = Stream("a", "b", "c")
s1: scala.collection.immutable.Stream[java.lang.String] = Stream(a, ?)
scala> val s2 = Stream("1", "2", "3")
s2: scala.collection.immutable.Stream[java.lang.String] = Stream(1, ?)
scala> implicit object StreamApplicative extends Applicative[Stream] {
| def pure[A](a: => A) = Stream.continually(a)
| override def apply[A, B](f: Stream[A => B], xs: Stream[A]): Stream[B] = (f, xs).zipped.map(_ apply _)
| }
defined module StreamApplicative
scala> (s1 |@| s2)(_ + _)
res101: scala.collection.immutable.Stream[java.lang.String] = Stream(a1, ?)
scala> .force
res102: scala.collection.immutable.Stream[java.lang.String] = Stream(a1, b2, c3)
不能用严格的列表来完成这一点的原因是因为不可能定义一个pure
满足适用法律的它们。
顺便说一句,Scala 可以让您比 OP 中使用的代码更简洁地完成此操作:
scala> (l1, l2).zipped.map(_ + _)
res103: List[java.lang.String] = List(a1, b2, c3)