From e88b404d344132dce6dd6891f8506fdf5d60d0cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C9=AF=CE=BBrv=C2=AC?= Date: Tue, 23 Jun 2020 13:07:13 +0100 Subject: [PATCH] Add Iso involuton (#869) * Add Iso involuton + Corresponding tests * Simplify comment block --- core/shared/src/main/scala/monocle/Iso.scala | 4 ++++ .../src/test/scala/monocle/IsoSpec.scala | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/core/shared/src/main/scala/monocle/Iso.scala b/core/shared/src/main/scala/monocle/Iso.scala index 94e88f295..ec41a2bf8 100644 --- a/core/shared/src/main/scala/monocle/Iso.scala +++ b/core/shared/src/main/scala/monocle/Iso.scala @@ -336,6 +336,10 @@ object Iso { /** alias for [[PIso]] id when S = T and A = B */ def id[S]: Iso[S, S] = PIso.id[S, S] + + /** create an [[Iso]] from a function that is its own inverse */ + def involuted[A](update: A => A): Iso[A, A] = + Iso(update)(update) } sealed abstract class IsoInstances { diff --git a/test/shared/src/test/scala/monocle/IsoSpec.scala b/test/shared/src/test/scala/monocle/IsoSpec.scala index bb115224d..ca2bc728c 100644 --- a/test/shared/src/test/scala/monocle/IsoSpec.scala +++ b/test/shared/src/test/scala/monocle/IsoSpec.scala @@ -39,6 +39,9 @@ class IsoSpec extends MonocleSuite { implicit def emptyCaseTypeEq[A] = Eq.fromUniversalEquals[EmptyCaseType[A]] val iso = Iso[IntWrapper, Int](_.i)(IntWrapper.apply) + val involutedListReverse = + Iso.involuted[List[Int]](_.reverse) // ∀ {T} -> List(ts: T*).reverse.reverse == List(ts: T*) + val involutedTwoMinusN = Iso.involuted[Int](2 - _) // ∀ {n : Int} -> n == 2 - (2 - n) checkAll("apply Iso", IsoTests(iso)) checkAll("GenIso", IsoTests(GenIso[IntWrapper, Int])) @@ -49,6 +52,9 @@ class IsoSpec extends MonocleSuite { checkAll("Iso id", IsoTests(Iso.id[Int])) + checkAll("Iso involutedListReverse", IsoTests(involutedListReverse)) + checkAll("Iso involutedTwoMinusN", IsoTests(involutedTwoMinusN)) + checkAll("Iso.asLens", LensTests(iso.asLens)) checkAll("Iso.asPrism", PrismTests(iso.asPrism)) checkAll("Iso.asOptional", OptionalTests(iso.asOptional)) @@ -122,6 +128,20 @@ class IsoSpec extends MonocleSuite { iso.modify(_ + 1)(IntWrapper(0)) shouldEqual IntWrapper(1) } + test("involuted") { + involutedListReverse.get(List(1, 2, 3)) shouldEqual List(3, 2, 1) + involutedListReverse.reverseGet(List(1, 2, 3)) shouldEqual List(3, 2, 1) + + involutedListReverse.reverse.get(List(1, 2, 3)) shouldEqual involutedListReverse.get(List(1, 2, 3)) + involutedListReverse.reverse.reverseGet(List(1, 2, 3)) shouldEqual involutedListReverse.reverseGet(List(1, 2, 3)) + + involutedTwoMinusN.get(5) shouldEqual -3 + involutedTwoMinusN.reverseGet(5) shouldEqual -3 + + involutedTwoMinusN.reverse.get(5) shouldEqual involutedTwoMinusN.get(5) + involutedTwoMinusN.reverse.reverseGet(5) shouldEqual involutedTwoMinusN.reverseGet(5) + } + test("GenIso nullary equality") { GenIso.unit[Nullary] shouldEqual _nullary }