Skip to content

Instantly share code, notes, and snippets.

@danicheg
Last active May 20, 2018 19:13
Show Gist options
  • Save danicheg/d5ee5bdfbc45ed2d899720a3b00469ad to your computer and use it in GitHub Desktop.
Save danicheg/d5ee5bdfbc45ed2d899720a3b00469ad to your computer and use it in GitHub Desktop.
package data
import monocle.Lens
trait HasLens[A, B] {
def lens: Lens[A, B]
}
object HasLens extends HasLensSyntax0
private[data] final case class HasLensOps[A, B](l: Lens[A, B]) extends AnyVal {
def toHasLens: HasLens[A, B] = new HasLens[A, B] {
val lens: Lens[A, B] = l
}
}
private[data] trait HasLensSyntax0 {
implicit def hasLensSyntax[A, B](lens: Lens[A, B]): HasLensOps[A, B] = HasLensOps(lens)
}
package data
import cats.implicits._
import cats.Monad
import cats.mtl.MonadState
trait MonadStateLens[F[_], S, A] {
def get: F[A]
def set(a: A): F[Unit]
def modify(f: A => A): F[Unit]
def inspect[C](f: A => C): F[C]
}
object MonadStateLens {
def apply[F[_], S, A](implicit FMS: MonadState[F, S], L: HasLens[S, A]): MonadStateLens[F, S, A] =
new MonadStateLens[F, S, A] {
implicit val m: Monad[F] = FMS.monad
def get: F[A] =
FMS.get.map(L.lens.get)
def set(a: A): F[Unit] =
FMS.get.flatMap(s => FMS.set(L.lens.set(a)(s)))
def modify(f: A => A): F[Unit] =
FMS.get.flatMap(s => FMS.set(L.lens.modify(f)(s)))
def inspect[C](f: A => C): F[C] =
FMS.get.map(s => f(L.lens.get(s)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment