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

add inheritance for applied optics #1116

Merged
merged 2 commits into from
Mar 8, 2021
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
22 changes: 11 additions & 11 deletions core/shared/src/main/scala/monocle/syntax/Applied.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,33 @@ object applied extends AppliedSyntax

trait AppliedSyntax {
implicit def toAppliedFoldOps[S](value: S): AppliedFoldOps[S] =
new AppliedFoldOps(value)
AppliedFoldOps(value)
implicit def toAppliedGetterOps[S](value: S): AppliedGetterOps[S] =
new AppliedGetterOps(value)
AppliedGetterOps(value)
implicit def toAppliedIsoOps[S](value: S): AppliedIsoOps[S] =
new AppliedIsoOps(value)
AppliedIsoOps(value)
implicit def toAppliedLensOps[S](value: S): AppliedLensOps[S] =
new AppliedLensOps(value)
AppliedLensOps(value)
implicit def toAppliedOptionalOps[S](value: S): AppliedOptionalOps[S] =
new AppliedOptionalOps(value)
AppliedOptionalOps(value)
implicit def toAppliedPrismOps[S](value: S): AppliedPrismOps[S] =
new AppliedPrismOps(value)
AppliedPrismOps(value)
implicit def toAppliedSetterOps[S](value: S): AppliedSetterOps[S] =
new AppliedSetterOps(value)
AppliedSetterOps(value)
implicit def toAppliedTraversalOps[S](value: S): AppliedTraversalOps[S] =
new AppliedTraversalOps(value)
AppliedTraversalOps(value)
}

final case class AppliedFoldOps[S](private val s: S) extends AnyVal {
@deprecated("use focus().andThen", since = "3.0.0-M1")
def applyFold[A](fold: Fold[S, A]): AppliedFold[S, A] =
new AppliedFold[S, A](s, fold)
AppliedFold[S, A](s, fold)
}

final case class AppliedGetterOps[S](private val s: S) extends AnyVal {
@deprecated("use focus().andThen", since = "3.0.0-M1")
def applyGetter[A](getter: Getter[S, A]): AppliedGetter[S, A] =
new AppliedGetter[S, A](s, getter)
AppliedGetter[S, A](s, getter)
}

final case class AppliedIsoOps[S](private val s: S) extends AnyVal {
Expand Down Expand Up @@ -85,7 +85,7 @@ final case class AppliedPrismOps[S](private val s: S) extends AnyVal {
final case class AppliedSetterOps[S](private val s: S) extends AnyVal {
@deprecated("use focus().andThen", since = "3.0.0-M1")
def applySetter[T, A, B](setter: PSetter[S, T, A, B]): AppliedPSetter[S, T, A, B] =
new AppliedPSetter[S, T, A, B](s, setter)
AppliedPSetter[S, T, A, B](s, setter)
}

final case class AppliedTraversalOps[S](private val s: S) extends AnyVal {
Expand Down
133 changes: 81 additions & 52 deletions core/shared/src/main/scala/monocle/syntax/AppliedFold.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,95 +2,124 @@ package monocle.syntax

import cats.Monoid
import monocle.function.{At, Each, FilterIndex, Index}
import monocle.{std, Fold, Getter, Optional, PIso, PLens, POptional, PPrism, PTraversal}
import monocle._

case class AppliedFold[S, A](s: S, _fold: Fold[S, A]) {
def foldMap[M: Monoid](f: A => M): M = _fold.foldMap(f)(s)
trait AppliedFold[S, A] {
def value: S
def optic: Fold[S, A]

def getAll: List[A] = _fold.getAll(s)
def find(p: A => Boolean): Option[A] = _fold.find(p)(s)
def headOption: Option[A] = _fold.headOption(s)
def lastOption: Option[A] = _fold.lastOption(s)
def exist(p: A => Boolean): Boolean = _fold.exist(p)(s)
def all(p: A => Boolean): Boolean = _fold.all(p)(s)
def length: Int = _fold.length(s)
def isEmpty: Boolean = _fold.isEmpty(s)
def nonEmpty: Boolean = _fold.nonEmpty(s)
def foldMap[M: Monoid](f: A => M): M = optic.foldMap(f)(value)

def getAll: List[A] = optic.getAll(value)
def find(p: A => Boolean): Option[A] = optic.find(p)(value)
def headOption: Option[A] = optic.headOption(value)
def lastOption: Option[A] = optic.lastOption(value)
def exist(p: A => Boolean): Boolean = optic.exist(p)(value)
def all(p: A => Boolean): Boolean = optic.all(p)(value)
def length: Int = optic.length(value)
def isEmpty: Boolean = optic.isEmpty(value)
def nonEmpty: Boolean = optic.nonEmpty(value)

def some[A1](implicit ev1: A =:= Option[A1]): AppliedFold[S, A1] =
adapt[Option[A1]].andThen(std.option.some[A1])

private[monocle] def adapt[A1](implicit evA: A =:= A1): AppliedFold[S, A1] =
evA.substituteCo[AppliedFold[S, *]](this)

def andThen[B](other: Fold[A, B]): AppliedFold[S, B] =
AppliedFold(value, optic.andThen(other))
}

object AppliedFold {
def apply[S, A](_value: S, _optic: Fold[S, A]): AppliedFold[S, A] =
new AppliedFold[S, A] {
val value: S = _value
val optic: Fold[S, A] = _optic
}

implicit def appliedFoldSyntax[S, A](self: AppliedFold[S, A]): AppliedFoldSyntax[S, A] =
new AppliedFoldSyntax(self)
}

final case class AppliedFoldSyntax[S, A](private val self: AppliedFold[S, A]) extends AnyVal {
def each[C](implicit evEach: Each[A, C]): AppliedFold[S, C] =
andThen(evEach.each)
self.andThen(evEach.each)

/** Select all the elements which satisfies the predicate.
* This combinator can break the fusion property see Optional.filter for more details.
*/
def filter(predicate: A => Boolean): AppliedFold[S, A] =
andThen(Optional.filter(predicate))
self.andThen(Optional.filter(predicate))

def filterIndex[I, A1](predicate: I => Boolean)(implicit ev: FilterIndex[A, I, A1]): AppliedFold[S, A1] =
andThen(ev.filterIndex(predicate))
self.andThen(ev.filterIndex(predicate))

def some[A1](implicit ev1: A =:= Option[A1]): AppliedFold[S, A1] =
adapt[Option[A1]].andThen(std.option.some[A1])

def withDefault[A1](defaultValue: A1)(implicit ev1: A =:= Option[A1]): AppliedFold[S, A1] =
adapt[Option[A1]].andThen(std.option.withDefault(defaultValue))
def withDefault[A1](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): AppliedFold[S, A1] =
self.adapt[Option[A1]].andThen(std.option.withDefault(defaultValue))

def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): AppliedFold[S, A1] =
andThen(evAt.at(i))
self.andThen(evAt.at(i))

def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): AppliedFold[S, A1] =
andThen(evIndex.index(i))

private def adapt[A1](implicit evA: A =:= A1): AppliedFold[S, A1] =
evA.substituteCo[AppliedFold[S, *]](this)

def andThen[B](other: Fold[A, B]): AppliedFold[S, B] =
AppliedFold(s, _fold.andThen(other))
def andThen[B](other: Getter[A, B]): AppliedFold[S, B] =
AppliedFold(s, _fold.andThen(other))
def andThen[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] =
AppliedFold(s, _fold.andThen(other))
def andThen[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] =
AppliedFold(s, _fold.andThen(other))
def andThen[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] =
AppliedFold(s, _fold.andThen(other))
def andThen[B, C, D](other: PLens[A, B, C, D]): AppliedFold[S, C] =
AppliedFold(s, _fold.andThen(other))
def andThen[B, C, D](other: PIso[A, B, C, D]): AppliedFold[S, C] =
AppliedFold(s, _fold.andThen(other))
self.andThen(evIndex.index(i))

/** compose a [[Fold]] with a [[Fold]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeFold[B](other: Fold[A, B]): AppliedFold[S, B] = andThen(other)
def composeFold[C](other: Fold[A, C]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[Getter]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeGetter[B](other: Getter[A, B]): AppliedFold[S, B] = andThen(other)
def composeGetter[C](other: Getter[A, C]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[PTraversal]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeTraversal[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def composeTraversal[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[POptional]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeOptional[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def composeOptional[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[PPrism]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composePrism[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def composePrism[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[PLens]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeLens[B, C, D](other: PLens[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def composeLens[B, C, D](other: PLens[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[PIso]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeIso[B, C, D](other: PIso[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def composeIso[B, C, D](other: PIso[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** alias to composeTraversal */
@deprecated("use andThen", since = "3.0.0-M1")
def ^|->>[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def ^|->>[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** alias to composeOptional */
@deprecated("use andThen", since = "3.0.0-M1")
def ^|-?[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def ^|-?[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** alias to composePrism */
@deprecated("use andThen", since = "3.0.0-M1")
def ^<-?[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def ^<-?[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** alias to composeLens */
@deprecated("use andThen", since = "3.0.0-M1")
def ^|->[B, C, D](other: PLens[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def ^|->[B, C, D](other: PLens[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** alias to composeIso */
@deprecated("use andThen", since = "3.0.0-M1")
def ^<->[B, C, D](other: PIso[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def ^<->[B, C, D](other: PIso[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)
}
119 changes: 72 additions & 47 deletions core/shared/src/main/scala/monocle/syntax/AppliedGetter.scala
Original file line number Diff line number Diff line change
@@ -1,75 +1,100 @@
package monocle.syntax

import monocle.function.{At, Each, FilterIndex, Index}
import monocle.{std, Fold, Getter, Optional, PIso, PLens, POptional, PPrism, PTraversal}
import monocle._
import monocle.function.At

final case class AppliedGetter[S, A](s: S, getter: Getter[S, A]) {
def get: A = getter.get(s)
def exist(p: A => Boolean): Boolean = getter.exist(p)(s)
def find(p: A => Boolean): Option[A] = getter.find(p)(s)
trait AppliedGetter[S, A] extends AppliedFold[S, A] {

def each[C](implicit evEach: Each[A, C]): AppliedFold[S, C] =
andThen(evEach.each)
override def optic: Getter[S, A]

/** Select all the elements which satisfies the predicate.
* This combinator can break the fusion property see Optional.filter for more details.
*/
def filter(predicate: A => Boolean): AppliedFold[S, A] =
andThen(Optional.filter(predicate))
def get: A = optic.get(value)

def filterIndex[I, A1](predicate: I => Boolean)(implicit ev: FilterIndex[A, I, A1]): AppliedFold[S, A1] =
andThen(ev.filterIndex(predicate))

def some[A1](implicit ev1: A =:= Option[A1]): AppliedFold[S, A1] =
override def some[A1](implicit ev1: A =:= Option[A1]): AppliedFold[S, A1] =
adapt[Option[A1]].andThen(std.option.some[A1])

def withDefault[A1](defaultValue: A1)(implicit ev1: A =:= Option[A1]): AppliedGetter[S, A1] =
adapt[Option[A1]].andThen(std.option.withDefault(defaultValue))
override private[monocle] def adapt[A1](implicit evA: A =:= A1): AppliedGetter[S, A1] =
evA.substituteCo[AppliedGetter[S, *]](this)

def andThen[B](other: Getter[A, B]): AppliedGetter[S, B] =
AppliedGetter(value, optic.andThen(other))
}

object AppliedGetter {
def apply[S, A](_value: S, _optic: Getter[S, A]): AppliedGetter[S, A] =
new AppliedGetter[S, A] {
val value: S = _value
val optic: Getter[S, A] = _optic
}

implicit def appliedGetterSyntax[S, A](self: AppliedGetter[S, A]): AppliedGetterSyntax[S, A] =
new AppliedGetterSyntax(self)
}

final case class AppliedGetterSyntax[S, A](private val self: AppliedGetter[S, A]) extends AnyVal {

def withDefault[A1](defaultValue: A1)(implicit evOpt: A =:= Option[A1]): AppliedGetter[S, A1] =
self.adapt[Option[A1]].andThen(std.option.withDefault(defaultValue))

def at[I, A1](i: I)(implicit evAt: At[A, i.type, A1]): AppliedGetter[S, A1] =
andThen(evAt.at(i))
self.andThen(evAt.at(i))

def index[I, A1](i: I)(implicit evIndex: Index[A, I, A1]): AppliedFold[S, A1] =
andThen(evIndex.index(i))
/** compose a [[Fold]] with a [[Fold]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeFold[C](other: Fold[A, C]): AppliedFold[S, C] =
self.andThen(other)

private def adapt[A1](implicit evA: A =:= A1): AppliedGetter[S, A1] =
evA.substituteCo[AppliedGetter[S, *]](this)
/** compose a [[Fold]] with a [[Getter]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeGetter[C](other: Getter[A, C]): AppliedGetter[S, C] =
self.andThen(other)

def andThen[B](other: Fold[A, B]): AppliedFold[S, B] =
AppliedFold(s, getter.andThen(other))
def andThen[B](other: Getter[A, B]): AppliedGetter[S, B] =
AppliedGetter(s, getter.andThen(other))
def andThen[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] =
AppliedFold(s, getter.andThen(other))
def andThen[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] =
AppliedFold(s, getter.andThen(other))
def andThen[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] =
AppliedFold(s, getter.andThen(other))
def andThen[B, C, D](other: PLens[A, B, C, D]): AppliedGetter[S, C] =
AppliedGetter(s, getter.andThen(other))
def andThen[B, C, D](other: PIso[A, B, C, D]): AppliedGetter[S, C] =
AppliedGetter(s, getter.andThen(other))
/** compose a [[Fold]] with a [[PTraversal]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeTraversal[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[POptional]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeFold[B](other: Fold[A, B]): AppliedFold[S, B] = andThen(other)
def composeOptional[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[PPrism]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeGetter[B](other: Getter[A, B]): AppliedGetter[S, B] = andThen(other)
def composePrism[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[PLens]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeTraversal[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def composeLens[B, C, D](other: PLens[A, B, C, D]): AppliedGetter[S, C] =
self.andThen(other)

/** compose a [[Fold]] with a [[PIso]] */
@deprecated("use andThen", since = "3.0.0-M1")
def composeOptional[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def composeIso[B, C, D](other: PIso[A, B, C, D]): AppliedGetter[S, C] =
self.andThen(other)

/** alias to composeTraversal */
@deprecated("use andThen", since = "3.0.0-M1")
def composePrism[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] = andThen(other)
def ^|->>[B, C, D](other: PTraversal[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** alias to composeOptional */
@deprecated("use andThen", since = "3.0.0-M1")
def composeLens[B, C, D](other: PLens[A, B, C, D]): AppliedGetter[S, C] = andThen(other)
def ^|-?[B, C, D](other: POptional[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** alias to composePrism */
@deprecated("use andThen", since = "3.0.0-M1")
def composeIso[B, C, D](other: PIso[A, B, C, D]): AppliedGetter[S, C] = andThen(other)
def ^<-?[B, C, D](other: PPrism[A, B, C, D]): AppliedFold[S, C] =
self.andThen(other)

/** alias to composeLens */
@deprecated("use andThen", since = "3.0.0-M1")
def ^|->[B, C, D](other: PLens[A, B, C, D]): AppliedGetter[S, C] = andThen(other)
def ^|->[B, C, D](other: PLens[A, B, C, D]): AppliedGetter[S, C] =
self.andThen(other)

/** alias to composeIso */
@deprecated("use andThen", since = "3.0.0-M1")
def ^<->[B, C, D](other: PIso[A, B, C, D]): AppliedGetter[S, C] = andThen(other)
def ^<->[B, C, D](other: PIso[A, B, C, D]): AppliedGetter[S, C] =
self.andThen(other)
}
Loading