Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move Map instance for Each and FilterIndex from unsafe module to core #998

Merged
merged 2 commits into from
Dec 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions core/shared/src/main/scala/monocle/function/Each.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ object Each extends EachFunctions {

implicit def lazyListEach[A]: Each[LazyList[A], A] = fromTraverse

implicit def defaultMapEach[K, V]: Each[Map[K, V], V] =
Each(
new Traversal[Map[K, V], V] {
def modifyF[F[_]: Applicative](f: V => F[V])(s: Map[K, V]): F[Map[K, V]] =
s.foldLeft(Applicative[F].pure(Map.empty[K, V])) { case (acc, (k, v)) =>
Applicative[F].map2(f(v), acc)((head, tail) => tail + (k -> head))
}
}
)

implicit def listMapEach[K, V]: Each[ListMap[K, V], V] =
Each(
new Traversal[ListMap[K, V], V] {
Expand Down
16 changes: 16 additions & 0 deletions core/shared/src/main/scala/monocle/function/FilterIndex.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,22 @@ object FilterIndex extends FilterIndexFunctions {
implicit def lazyListFilterIndex[A]: FilterIndex[LazyList[A], Int, A] =
fromTraverse(_.zipWithIndex)

implicit def mapFilterIndex[K, V]: FilterIndex[Map[K, V], K, V] =
new FilterIndex[Map[K, V], K, V] {
import cats.syntax.applicative._
import cats.syntax.functor._

def filterIndex(predicate: K => Boolean) =
new Traversal[Map[K, V], V] {
def modifyF[F[_]: Applicative](f: V => F[V])(s: Map[K, V]): F[Map[K, V]] =
s.toList
.traverse { case (k, v) =>
(if (predicate(k)) f(v) else v.pure[F]).tupleLeft(k)
}
.map(_.toMap)
}
}

implicit def sortedMapFilterIndex[K, V](implicit ok: Order[K]): FilterIndex[SortedMap[K, V], K, V] =
new FilterIndex[SortedMap[K, V], K, V] {
import cats.syntax.applicative._
Expand Down
4 changes: 2 additions & 2 deletions docs/src/main/mdoc/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ In an attempt to be modular, Monocle is broken up into several modules:
type class instances for standard library types and cats data types
* *macro* - macros to simplify the generation of optics
* *laws* - laws for the optics and type classes
* *refined* - optics and type class instances using refinement types from [refined](https://github.com/fthomas/refined)
* *generic* (deprecated) - optics and type class instances for `HList` and `Coproduct` from [shapeless](https://github.com/milessabin/shapeless)
* *state* (deprecated) - conversion between optics and `State` or `Reader`
* *refined* - optics and type class instances using refinement types from [refined](https://github.com/fthomas/refined)
* *unsafe* - optics that do not fully satisfy laws but that are very convenient. More details [here](unsafe_module.html)
* *unsafe* (deprecated) - optics that do not fully satisfy laws but that are very convenient. More details [here](unsafe_module.html)
* *tests* - tests that check optics and type class instances satisfy laws
* *bench* - benchmarks using jmh to measure optics performances
* *docs* - source for this website
Expand Down
1 change: 0 additions & 1 deletion example/src/test/scala/monocle/HttpRequestExample.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package monocle

import monocle.macros.{GenIso, GenLens, GenPrism}
import monocle.unsafe.MapTraversal._

/** Show how could we use Monocle to handle custom case classes, objects
*/
Expand Down
1 change: 0 additions & 1 deletion example/src/test/scala/monocle/JsonExample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package monocle

import alleycats.std.all._
import monocle.function.Plated
import monocle.unsafe.MapTraversal._

/** Show how could we use Optics to manipulate some Json AST
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ package monocle.function
import cats.kernel.Eq
import monocle.MonocleSuite
import monocle.law.discipline.function.EachTests
import scala.collection.immutable.ListMap

class EachSpec extends MonocleSuite {
implicit val eqListMap: Eq[ListMap[String, String]] = Eq.fromUniversalEquals
implicit val eqListMap: Eq[Map[String, String]] = Eq.fromUniversalEquals

implicit val slistEach: Each[CList, Char] = Each.fromIso(CList.toList)

checkAll("fromIso", EachTests[CList, Char])

checkAll("ListMap", EachTests[ListMap[String, String], String])
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package monocle.function

import cats.Order
import monocle.MonocleSuite
import monocle.law.discipline.function.FilterIndexTests

class FilterIndexSpec extends MonocleSuite {
implicit def mmapFilterIndex[K: Order, V]: FilterIndex[MSorteMap[K, V], K, V] =
FilterIndex.fromIso(MSorteMap.toSortedMap)
implicit def mmapFilterIndex[K, V]: FilterIndex[MMap[K, V], K, V] =
FilterIndex.fromIso(MMap.toMap)

checkAll("fromIso", FilterIndexTests[MSorteMap[Int, String], Int, String])
checkAll("fromIso", FilterIndexTests[MMap[Int, String], Int, String])
}
13 changes: 13 additions & 0 deletions test/shared/src/test/scala/monocle/std/ListMapSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package monocle.std

import cats.kernel.Eq
import monocle.MonocleSuite
import monocle.law.discipline.function._

import scala.collection.immutable.ListMap

class ListMapSpec extends MonocleSuite {
implicit val eqListMap: Eq[ListMap[Int, String]] = Eq.fromUniversalEquals

checkAll("each Map", EachTests[ListMap[Int, String], String])
}
1 change: 1 addition & 0 deletions test/shared/src/test/scala/monocle/std/MapSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import monocle.MonocleSuite
import monocle.law.discipline.function._

import scala.annotation.nowarn
import scala.collection.immutable.Map

class MapSpec extends MonocleSuite {
checkAll("at Map", AtTests[Map[Int, String], Int, Option[String]])
Expand Down

This file was deleted.

1 change: 1 addition & 0 deletions unsafe/src/main/scala/monocle/unsafe/MapTraversal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import monocle.function.{Each, FilterIndex}

import scala.collection.immutable.Map

@deprecated("use optic.filter(predicate)", since = "3.0.0-M1")
object MapTraversal {
implicit def mapEach[K, V]: Each[Map[K, V], V] = fromTraverse[Map[K, *], V]

Expand Down