2012-02-06 41 views
4

元素假設我們有兩個列表:結合的2所列出

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

我要的是:List("a1", "b2", "c3")即與L2

的一種方式的第n個元素添加L1的第n個元素實現它是:

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

我只是想知道是否可以用Applicative實現它。我想:

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

但它給所有的組合:

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

任何想法?

謝謝

伯努瓦

+0

你想要一個ziplist。 Haskell在http://en.wikibooks.org/wiki/Haskell/Applicative_Functors#ZipLists上有一個。我不確定斯卡拉茲是否有一個,但我也沒有看過。 – 2012-02-06 20:50:30

+0

@DerekWyatt:謝謝德里克。 missingfaktor已經提供了答案 – bhericher 2012-02-06 21:05:45

回答

3

答案是,你不能只要我可以看到一個適用實現這一目標。正如你發現的那樣,應用列表將把這個函數應用於所有的組合。對於你想要的東西不是很好,但對創造笛卡爾產品等東西很棒。

稍微更簡潔的方法可以使用由scalaz提供Tuple2W.fold

(l1 zip l2).map (_ fold (_ + _)) 
+0

或'Tuple2#zipped'。更簡潔。 – missingfaktor 2012-02-06 20:53:38

+0

@oxbow_lakes:謝謝。如果我正確理解,斯卡拉斯允許以更加愉快的方式與元組進行交易。這很酷! – bhericher 2012-02-06 21:04:26

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滿足可適用的法律。

順便說一句,斯卡拉可以讓你做到這一點比更簡潔您在OP使用的代碼:

scala> (l1, l2).zipped.map(_ + _) 
res103: List[java.lang.String] = List(a1, b2, c3) 
+0

謝謝你的回答和解釋!據我瞭解,它適用於Streams,因爲它們是懶惰的,它們的元素是一個接一個地進行的。對? – bhericher 2012-02-06 21:02:21

+0

@ user1193200,是的,它按需發生。 – missingfaktor 2012-02-06 21:03:09

+0

@missinglake:哇!你在這個論壇上遠離「懶惰」!這當然是「反應式編程」:) – bhericher 2012-02-06 21:08:44