Skip to content

Instantly share code, notes, and snippets.

@aoiroaoino
Last active March 28, 2018 12:40
Show Gist options
  • Select an option

  • Save aoiroaoino/5158e36f5858f8cfe12c8840d12fd19d to your computer and use it in GitHub Desktop.

Select an option

Save aoiroaoino/5158e36f5858f8cfe12c8840d12fd19d to your computer and use it in GitHub Desktop.
VL-Lens in Scala
import Dependencies._
lazy val root = (project in file(".")).
settings(
inThisBuild(List(
organization := "com.example",
scalaVersion := "2.11.11",
version := "0.1.0-SNAPSHOT"
)),
name := "vr-lens-demo",
libraryDependencies += scalaTest % Test,
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.2.20",
scalacOptions ++= Seq(
// "-Ypartial-unification",
"-language:higherKinds"
)
)
> console
[info] Starting scala interpreter...
[info]
Welcome to Scala 2.12.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.
scala> import example.lens.demo._
import example.lens.demo._
scala> val user = User(999, "aaa")
user: example.lens.demo.User = User(999,aaa)
scala> modify(_name)(user)(_.toUpperCase)
res0: example.lens.demo.User = User(999,AAA)
scala> get(_name)(user)
<console>:16: error: polymorphic expression cannot be instantiated to expected type;
found : [F[_]]example.lens.demo.Lens[F,example.lens.demo.User,String]
required: example.lens.demo.Getter[?,?]
(which expands to) example.lens.demo.Lens[[X]example.lens.demo.Const[?,X],?,?]
get(_name)(user)
^
scala> get(_name[({ type F[A] = Const[String, A]})#F])(user)
res2: String = aaa
package example.lens
import scalaz._, Id.Id
//import Scalaz._
object demo {
case class User(id: Long, name: String)
// type Id[A] = A
// case class Const[A, B](getConst: A)
// trait Functor[F[_]] {
// def map[A, B](fa: F[A])(f: A => B): F[B]
// }
// object Functor {
// def apply[F[_]](implicit F: Functor[F]): Functor[F] = F
//
// implicit val idFuncotr: Functor[Id] =
// new Functor[Id] {
// override def map[A, B](fa: Id[A])(f: A => B): Id[B] = f(fa)
// }
//
// implicit def constFunctor[A]: Functor[({ type F[X] = Const[A, X] })#F] =
// new Functor[({ type F[X] = Const[A, X] })#F] {
// override def map[B, C](fa: Const[A, B])(f: B => C): Const[A, C] =
// Const[A, C](fa.getConst)
// }
// }
trait Lens[F[_], S, A] {
def run(s: S)(f: A => F[A]): F[S]
}
type Setter[S, A] = Lens[Id, S, A]
def modify[S, A](setter: Setter[S, A])(s: S)(f: A => A): S =
setter.run(s)(f)
type Getter[S, A] = Lens[({ type F[X] = Const[A, X] })#F, S, A]
type Getting[R, S, A] = Lens[({ type F[X] = Const[R, X]})#F, S, A]
def get[S, A](getter: Getting[A, S, A])(s: S): A =
getter.run(s)(a => Const(a)).getConst
def _name[F[_]: Functor]: Lens[F, User, String] = new Lens[F, User, String] {
def run(user: User)(f: String => F[String]): F[User] =
Functor[F].map[String, User](f(user.name))(n => user.copy(name = n))
}
def _nameU(implicit U: Unapply[Functor, Const[String, User]]): Lens[U.M, User, String] =
new Lens[U.M, User, String] {
def run(user: User)(f: String => U.M[String]): U.M[User] =
U.TC.map(f(user.name))(n => user.copy(name = n))
}
}
@aoiroaoino
Copy link
Author

やったぜ(つらい

import scalaz._

object demo {
  // ...

  def _nameU(implicit U: Unapply[Functor, Const[String, User]]): Lens[U.M, User, String] =
    new Lens[U.M, User, String] {
      def run(user: User)(f: String => U.M[String]): U.M[User] =
        U.TC.map(f(user.name))(n => user.copy(name = n))
  }
}
scala> get(_nameU)(User(999, "aaa"))
res1: String = aaa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment