Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Odomontois/56e5ce56a3b8af518c1cb617886f813b to your computer and use it in GitHub Desktop.
Save Odomontois/56e5ce56a3b8af518c1cb617886f813b to your computer and use it in GitHub Desktop.
An example how to compile a higher-level language into a lower-level one with parameterised argument types in Free monads way
package scalagroup
import cats.Functor
import cats.instances.function._
import cats.instances.string._
import cats.syntax.eq._
import cats.syntax.functor._
import simulacrum.typeclass
object KVStore {
def main(args: Array[String]): Unit = {
trait KVStoreApi[Key, Value, F[_]] {
def get(key: Key): F[Option[Value]]
}
final case class User(username: String, password: String)
@typeclass trait UserApi[F[_]] {
def getUser(username: String, password: String): F[Option[User]]
}
implicit def userApiToKvInterpreter[F[_]: Functor](implicit kv: KVStoreApi[String, String, F]): UserApi[F] =
(username: String, password: String) =>
for (pass <- kv.get(username)) yield pass.filter(_ === password).map(User(username, _))
val store = Map("some_user" -> "some_password")
implicit val userKvToIdInterpreter: KVStoreApi[String, String, Map[String, String] => ?] =
key => map => map.get(key)
println(UserApi[Map[String, String] => ?].getUser("some_user", "some_password")(store))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment