monocle.function.Each.scala Maven / Gradle / Ivy
The newest version!
package monocle.function
import monocle.{Iso, PTraversal, Traversal}
import scala.annotation.implicitNotFound
import scala.collection.immutable.ListMap
import cats.{Applicative, Order, Traverse}
import cats.instances.lazyList._
/** Typeclass that defines a [[Traversal]] from a monomorphic container `S` to all of its elements of type `A`
* @tparam S source of [[Traversal]]
* @tparam A target of [[Traversal]], `A` is supposed to be unique for a given `S`
*/
@implicitNotFound(
"Could not find an instance of Each[${S},${A}], please check Monocle instance location policy to " + "find out which import is necessary"
)
abstract class Each[S, A] extends Serializable {
def each: Traversal[S, A]
}
trait EachFunctions {
def each[S, A](implicit ev: Each[S, A]): Traversal[S, A] = ev.each
}
object Each extends EachFunctions {
def apply[S, A](traversal: Traversal[S, A]): Each[S, A] =
new Each[S, A] {
override val each: Traversal[S, A] = traversal
}
/** lift an instance of [[Each]] using an [[Iso]] */
def fromIso[S, A, B](iso: Iso[S, A])(implicit ev: Each[A, B]): Each[S, B] =
Each(
iso composeTraversal ev.each
)
def fromTraverse[S[_]: Traverse, A]: Each[S[A], A] =
new Each[S[A], A] {
def each = PTraversal.fromTraverse[S, A, A]
}
/** *********************************************************************************************
*/
/** Std instances */
/** *********************************************************************************************
*/
import cats.instances.list._
import cats.instances.sortedMap._
import cats.instances.vector._
import scala.collection.immutable.SortedMap
import scala.util.Try
implicit def eitherEach[A, B]: Each[Either[A, B], B] =
new Each[Either[A, B], B] {
def each = monocle.std.either.stdRight.asTraversal
}
implicit def listEach[A]: Each[List[A], A] = fromTraverse
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] {
def modifyF[F[_]: Applicative](f: V => F[V])(s: ListMap[K, V]): F[ListMap[K, V]] =
s.foldLeft(Applicative[F].pure(ListMap.empty[K, V])) { case (acc, (k, v)) =>
Applicative[F].map2(f(v), acc)((head, tail) => tail + (k -> head))
}
}
)
implicit def mapEach[K: Order, V]: Each[SortedMap[K, V], V] =
fromTraverse[SortedMap[K, *], V]
implicit def optEach[A]: Each[Option[A], A] =
new Each[Option[A], A] {
def each = monocle.std.option.some[A].asTraversal
}
implicit val stringEach: Each[String, Char] = Each(
monocle.std.string.stringToList composeTraversal Each.each[List[Char], Char]
)
implicit def tryEach[A]: Each[Try[A], A] =
new Each[Try[A], A] {
def each = monocle.std.utilTry.trySuccess.asTraversal
}
implicit def tuple1Each[A]: Each[Tuple1[A], A] =
Each(
monocle.std.tuple1.tuple1Iso[A].asTraversal
)
implicit def tuple2Each[A]: Each[(A, A), A] =
Each(
PTraversal.apply2[(A, A), (A, A), A, A](_._1, _._2)((b1, b2, _) => (b1, b2))
)
implicit def tuple3Each[A]: Each[(A, A, A), A] =
Each(
PTraversal.apply3[(A, A, A), (A, A, A), A, A](_._1, _._2, _._3)((b1, b2, b3, _) => (b1, b2, b3))
)
implicit def tuple4Each[A]: Each[(A, A, A, A), A] =
Each(
PTraversal.apply4[(A, A, A, A), (A, A, A, A), A, A](_._1, _._2, _._3, _._4)((b1, b2, b3, b4, _) =>
(b1, b2, b3, b4)
)
)
implicit def tuple5Each[A]: Each[(A, A, A, A, A), A] =
Each(
PTraversal.apply5[(A, A, A, A, A), (A, A, A, A, A), A, A](_._1, _._2, _._3, _._4, _._5)((b1, b2, b3, b4, b5, _) =>
(b1, b2, b3, b4, b5)
)
)
implicit def tuple6Each[A]: Each[(A, A, A, A, A, A), A] =
Each(
PTraversal.apply6[(A, A, A, A, A, A), (A, A, A, A, A, A), A, A](_._1, _._2, _._3, _._4, _._5, _._6)(
(b1, b2, b3, b4, b5, b6, _) => (b1, b2, b3, b4, b5, b6)
)
)
implicit def vectorEach[A]: Each[Vector[A], A] = fromTraverse
/** *********************************************************************************************
*/
/** Cats instances */
/** *********************************************************************************************
*/
import cats.data.{Chain, NonEmptyChain, NonEmptyList, NonEmptyVector, OneAnd, Validated}
import cats.free.Cofree
implicit def cofreeEach[S[_]: Traverse, A]: Each[Cofree[S, A], A] =
fromTraverse[Cofree[S, *], A]
implicit def chainEach[A]: Each[Chain[A], A] = fromTraverse
implicit def necEach[A]: Each[NonEmptyChain[A], A] = fromTraverse
implicit def nelEach[A]: Each[NonEmptyList[A], A] = fromTraverse
implicit def nevEach[A]: Each[NonEmptyVector[A], A] = fromTraverse
implicit def oneAndEach[T[_], A](implicit ev: Each[T[A], A]): Each[OneAnd[T, A], A] =
Each(
new Traversal[OneAnd[T, A], A] {
def modifyF[F[_]: Applicative](f: A => F[A])(s: OneAnd[T, A]): F[OneAnd[T, A]] =
Applicative[F].map2(f(s.head), ev.each.modifyF(f)(s.tail))((head, tail) => new OneAnd(head, tail))
}
)
implicit def validatedEach[A, B]: Each[Validated[A, B], B] =
new Each[Validated[A, B], B] {
def each = monocle.std.validated.success.asTraversal
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy