Skip to content

Commit

Permalink
add unzip to Functor (#3062)
Browse files Browse the repository at this point in the history
* added unzip method to Functor typeClass

* fixed formatting

* added @noop on unzip, to fix issue with Simulacrum-generated extension method

* remove exclusion from build.sbt

* updated unzip declaration to include implicit pair derivation, removed noop

* changed signature back to the original proposal
  • Loading branch information
gagandeepkalra authored and LukaJCB committed Nov 6, 2019
1 parent fc7b8b9 commit 254ec63
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
19 changes: 18 additions & 1 deletion core/src/main/scala/cats/Functor.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cats

import simulacrum.typeclass
import simulacrum.{noop, typeclass}

/**
* Functor.
Expand Down Expand Up @@ -144,6 +144,23 @@ import simulacrum.typeclass
*/
def tupleRight[A, B](fa: F[A], b: B): F[(A, B)] = map(fa)(a => (a, b))

/**
* Un-zips an `F[(A, B)]` consisting of element pairs or Tuple2 into two separate F's tupled.
*
* NOTE: Check for effect duplication, possibly memoize before
*
* {{{
* scala> import cats.Functor
* scala> import cats.implicits.catsStdInstancesForList
*
* scala> Functor[List].unzip(List((1,2), (3, 4)))
* res0: (List[Int], List[Int]) = (List(1, 3),List(2, 4))
* }}}
*
*/
@noop
def unzip[A, B](fab: F[(A, B)]): (F[A], F[B]) = (map(fab)(_._1), map(fab)(_._2))

/**
* Lifts `if` to Functor
*
Expand Down
8 changes: 8 additions & 0 deletions tests/src/test/scala/cats/tests/FunctorSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ class FunctorSuite extends CatsSuite {
}
}

test("unzip preserves structure") {
forAll { (l: List[Int], o: Option[Int], m: Map[String, Int]) =>
Functor[List].unzip(l.map(i => (i, i))) === ((l, l))
Functor[Option].unzip(o.map(i => (i, i))) === ((o, o))
Functor[Map[String, *]].unzip(m.map { case (k, v) => (k, (v, v)) }) === ((m, m))
}
}

test("widen equals map(identity)") {
forAll { (i: Int) =>
val list: List[Some[Int]] = List(Some(i))
Expand Down

0 comments on commit 254ec63

Please sign in to comment.