4

2つのリストがあると仮定します。

val l1=List("a","b","c")
val l2 = List("1","2","3")

私が欲しいのは:List("a1", "b2", "c3")つまり、l1のn番目の要素をl2のn番目の要素に追加することです

それを達成する方法は次のとおりです。

(l1 zip l2).map (c => {c._1+c._2})

Applicativeでそれを達成できるかどうかだけ疑問に思います。私は試した :

(l1 |@| l2) { _+ _ } 

しかし、それはすべての組み合わせを与えます:

List(a1, a2, a3, b1, b2, b3, c1, c2, c3)

何か案が?

ありがとうございました

ブノワ

4

2 に答える 2

5

厳密なリストではそれを行うことができないため、代わりに遅延リスト、つまりストリームを使用してください。Applicative[Stream]以下に示すようにインスタンスを定義する必要があります。(ZipList という名前で Haskell 標準ライブラリにあります。)

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、適用法を満たす a をそれらに定義することが不可能だからです。

余談ですが、Scala を使用すると、OP で使用したコードよりも簡潔にこれを行うことができます。

scala> (l1, l2).zipped.map(_ + _)
res103: List[java.lang.String] = List(a1, b2, c3)
于 2012-02-06T20:50:47.310 に答える
3

答えは、私が見る限り、アプリケーションではこれを達成できないということです。お気づきのように、applicative for list はすべての組み合わせに関数を適用します。あなたが望むものには適していませんが、デカルト積の作成などには最適です。

少し冗長な方法はTuple2W.fold、scalaz が提供するものを使用するかもしれません:

(l1 zip l2).map (_ fold (_ + _))
于 2012-02-06T20:45:38.803 に答える