Review
A Review
is a write-only Prism, It
describes how to construct a single value. It's a dual of Getter.
Constructing a monomorphic Review
Review[S, A]
is constructed using the Review[S, A]#apply function.
For a given Review[S, A]
it takes a function review: A => S
as argument.
object Review {
def apply[S, A](f: A => S): Review[S, A]
}
import proptics.Review
def fibonacci(a: Int, b: Int): LazyList[Int] = a #:: fibonacci(b, a + b)
val review = Review[List[Int], Int](n => fibonacci(0, 1).take(n).toList)
review.review(7)
// val res0: List[Int] = List(0, 1, 1, 2, 3, 5, 8)
Constructing a polymorphic Review
Review_[S, T, A, B]
is constructed using the Review_[S, T, A, B]#apply function.
For a given Review_[S, T, A, B]
it takes a function review: B => T
as argument.
object Review_ {
def apply[S, T, A, B](f: B => T): Review[S, T, A, B]
}
Methods
review
/** view the modified source of a Review */
def review(a: A): S
import proptics.Review
final case class Whole(part: Int)
val wholeReview = Review[Whole, Int](Whole.apply)
wholeReview.review(9)
// val res0: Whole = Whole(9)
use
/** view the modified focus of a Review in the state of a monad */
def use(implicit ev: cats.data.State[A, S]): State[A, S]
import cats.data.State
import proptics.Review
final case class Whole(part: Int)
implicit val state: State[Int, Whole] = State.pure[Int, Whole](Whole(1))
val wholeReview = Review[Whole, Int](Whole.apply)
wholeReview.use.runA(9).value
// val res1: Whole = Whole(9)
Review internal encoding
Polymorphic Review
Review_[S, T, A, B]
Review_[S, T, A, B]
is a function Tagged[A, B] => Tagged[S, T]
. Tagged is a data type shaped like a profunctor, which ignores it's first type parameter.
/**
* @tparam S the source of a Review_
* @tparam T the modified source of a Review_
* @tparam A the focus of a Review_
* @tparam B the modified focus of a Review_
*/
abstract class Review_[S, T, A, B] {
def apply(tagged: Tagged[A, B]): Tagged[S, T]
}
Review_[S, T, A, B]
changes its focus from A
to B
, resulting in a change of structure from S
to T
.
A Review
that changes its focus/structure, is called Polymorphic Review
.
Monomorphic Review
Review[S, A]
Review[S, A]
is a type alias for Review_[S, S, A, A]
, which has the same type of focus A
, thus preserving the same type of structure S
.
type Review[S, A] = Review_[S, S, A, A]
A Review
that does not change its focus/structure, is called Monomorphic Review
.
Since Review
is write-only, Review[T, B]
is isomorphic to Review_[S, T, A, B]
.
Review_[S, T, A, B]
takes Tagged[A, B]
which wraps a value of B
and ignores the A
, and returns Tagged[S, T]
which wraps a value T
and ignores the S
, and its representation can be simplified to:
B => T
Let's compare it to Review[T, T, B, B]
which is equivalent to Review[T, B]
.
def review[T, B]: Review[T, B] = new Review_[T, T, B, B] {
def apply(tagged: Tagged[B, B]): Tagged[T, T]
}
Review[T, T, B, B]
takes Tagged[B, B]
which wraps a value B
and ignores the first type parameter B
, and returns Tagged[T, T]
which wraps a value T
and ignores the first type parameter T
,
and its representation can be simplified to:
B => T
Laws
Since a Review
cannot be used to read back there are no laws that can be applied to it.