# scalaz/scalaz

fix intercalate on List and Vector

1 parent b132e90 commit cc83f9ed5398619d9cd9a1ea43e1b0442f56d03a purefn committed Jul 31, 2012
11 core/src/main/scala/scalaz/std/List.scala
 @@ -116,16 +116,7 @@ trait ListFunctions { intersperse0(Nil, as).reverse } - final def intercalate[A](as1: List[A], as2: List[A]): List[A] = { - val asr = as2.reverse - @tailrec - def intercalate0(accum: List[A], rest: List[A]): List[A] = rest match { - case Nil => accum - case x :: Nil => x :: accum - case h :: t => intercalate0(asr ::: h :: accum, t) - } - intercalate0(Nil, as1).reverse - } + final def intercalate[A](as1: List[List[A]], as2: List[A]): List[A] = intersperse(as1, as2).flatten final def toNel[A](as: List[A]): Option[NonEmptyList[A]] = as match { case Nil => None
8 core/src/main/scala/scalaz/std/Vector.scala
 @@ -76,13 +76,7 @@ trait VectorFunctions { intersperse0(Vector(), as).reverse } - final def intercalate[A](as1: Vector[A], as2: Vector[A]): Vector[A] = { - val asr = as2.reverse - @tailrec - def intercalate0(accum: Vector[A], rest: Vector[A]): Vector[A] = - if (rest.isEmpty) accum else if (rest.tail.isEmpty) rest.head +: accum else intercalate0(asr ++ (rest.head +: accum), rest.tail) - intercalate0(Vector(), as1).reverse - } + final def intercalate[A](as1: Vector[Vector[A]], as2: Vector[A]): Vector[A] = intersperse(as1, as2).flatten final def toNel[A](as: Vector[A]): Option[NonEmptyList[A]] = if (as.isEmpty) None else Some(NonEmptyList.nel(as.head, as.tail.toList))
2 core/src/main/scala/scalaz/syntax/std/ListOps.scala
 @@ -9,7 +9,7 @@ trait ListOps[A] extends Ops[List[A]] { final def intersperse(a: A): List[A] = l.intersperse(self, a) - final def intercalate(other: List[A]): List[A] = l.intercalate(self, other) + final def intercalate[B](other: List[B])(implicit ev: List[A] =:= List[List[B]]): List[B] = l.intercalate(self, other) final def toNel: Option[NonEmptyList[A]] = l.toNel(self)
2 core/src/main/scala/scalaz/syntax/std/VectorOps.scala
 @@ -8,7 +8,7 @@ trait VectorOps[A] extends Ops[Vector[A]] { final def intersperse(a: A): Vector[A] = v.intersperse(self, a) - final def intercalate(other: Vector[A]): Vector[A] = v.intercalate(self, other) + final def intercalate[B](other: Vector[B])(implicit ev: Vector[A] =:= Vector[Vector[B]]): Vector[B] = v.intercalate(self, other) final def toNel: Option[NonEmptyList[A]] = v.toNel(self)
17 tests/src/test/scala/scalaz/std/ListTest.scala
 @@ -14,17 +14,17 @@ class ListTest extends Spec { import std.list.listSyntax._ import syntax.monad._ - "intercalate empty list is identity" ! check((a: List[Int]) => a.intercalate(Nil) must be_===(a)) + "intercalate empty list is flatten" ! check((a: List[List[Int]]) => a.intercalate(List[Int]()) must be_===(a.flatten)) "intersperse then remove odd items is identity" ! check { (a: List[Int], b: Int) => val isEven = (_: Int) % 2 == 0 a.intersperse(b).zipWithIndex.filter(p => isEven(p._2)).map(_._1) must be_===(a) } - "intercalate single element lists the same as intersperse" ! check { - (a: List[Int], b: Int) => - a.intercalate(List(b)) must be_===(a.intersperse(b)) + "intercalate is same as a.intersperse(b).flatten" ! check { + (a: List[List[Int]], b: List[Int]) => + a.intercalate(b) must be_===(a.intersperse(b).flatten) } "intersperse vs benchmark" ! check { @@ -36,15 +36,6 @@ class ListTest extends Spec { (a: List[Int], b: Int) => (a.intersperse(b) must be_===(intersperse(a, b))) } - "intercalate vs benchmark" ! check { - def intercalate[A](value: List[A], as: List[A]): List[A] = value match { - case Nil => Nil - case x :: Nil => x :: Nil - case h :: t => h :: as ::: intercalate(t, as) - } - (a: List[Int], b: List[Int]) => (a.intercalate(b) must be_===(intercalate(a, b))) - } - "groupByM[Id].flatten is identity" ! check { (a: List[Int], p: (Int, Int) => Boolean) => a.groupByM[Id]((a, b) => p(a, b)).flatten must be_===(a)