Skip to content

Instantly share code, notes, and snippets.

@REDNBLACK
Last active June 14, 2019 08:41
Show Gist options
  • Save REDNBLACK/94e15bfa189e37584092b29e2252c6cd to your computer and use it in GitHub Desktop.
Save REDNBLACK/94e15bfa189e37584092b29e2252c6cd to your computer and use it in GitHub Desktop.

Revisions

  1. Boris revised this gist Jun 14, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Monocle.scala
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    package ru.tinkoff
    package pkg

    import cats.{Applicative, Traverse}

  2. Boris created this gist Jun 14, 2019.
    62 changes: 62 additions & 0 deletions Monocle.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    package ru.tinkoff

    import cats.{Applicative, Traverse}

    import monocle.macros.{GenLens, Lenses}
    import monocle.macros.syntax.lens._
    import monocle.function.all._
    import cats.syntax.option._

    import monocle.Traversal
    import monocle.function.FilterIndex.fromTraverse
    import monocle.function.{FilterIndex, FilterIndexFunctions}

    object Demo extends App {
    @Lenses
    case class Company(name: String, employees: List[Employee])

    @Lenses
    case class Employee(name: String, data: List[Field])

    @Lenses
    case class Field(name: String, value: Option[String])

    val company1 = Company("awesome inc", List(
    Employee("Steven", Field("age", "20".some) :: Nil),
    Employee("Carl", Field("age", "30".some) :: Nil),
    Employee("Max", Field("married", "true".some) :: Nil)
    ))


    object Impl {
    abstract class Filter[S, A] extends Serializable {
    def filter(predicate: A => Boolean): Traversal[S, A]
    }

    trait FilterFunctions {
    def filter[S, A](predicate: A => Boolean)(implicit ev: Filter[S, A]): Traversal[S, A] = ev.filter(predicate)

    def filterNot[S, A](predicate: A => Boolean)(implicit ev: Filter[S, A]): Traversal[S, A] = ev.filter(!predicate(_))
    }

    object Filter extends FilterFunctions {
    import cats.syntax.traverse._
    import cats.syntax.applicative._

    implicit def traverseFilter[S[_]: Traverse, A]: Filter[S[A], A] = predicate => new Traversal[S[A], A] {
    def modifyF[F[_]: Applicative](f: A => F[A])(s: S[A]): F[S[A]] =
    s.traverse(a => if (predicate(a)) f(a) else a.pure[F])
    }
    }
    }

    import Impl.Filter._
    import cats.instances.list._

    val lens = GenLens[Company](_.employees) ^|->> each ^|-> GenLens[Employee](_.data) ^|->> filter((_: Field).name == "age") modify(
    _.copy(value = "100500".some)
    )

    println(company1)
    println(lens(company1))
    }