Skip to content

Instantly share code, notes, and snippets.

View qingwei91's full-sized avatar

Qing qingwei91

View GitHub Profile
// this is slow .....
def fib(i: Int): Int = i match {
case 0 => 0
case 1 => 1
case n => fib(n - 2) + fib(n - 1)
}
val cacheBackend = new CacheBackEnd[Int, Int]
def cachedFib(i: Int): Int = cache(fib)(cacheBackend)(i)
// the signature is slightly different, as our macro need to access `get` and `put` method, but not `getOrElse`
// you can implement both signature though
trait SyncCache[K, V] {
def get(k: K): Option[V]
def put(k: K, v: V): Unit
}
val cacheBackend = new SyncCache[Int, Int]
@cache(cacheBackend)
// @param backend - parameter for `cache` annotation
class cache[K, V](backend: SyncCache[K, V]) extends scala.annotation.StaticAnnotation {
// @param defn - the annotated method (it can also be other scala building block like class, but we are restricting here
// using some checks below
inline def apply(defn: Any): Any = meta {
defn match {
// this annotation should only be annotate on `method`, represented as `Defn.Def` in scalameta's AST
case defn: Defn.Def =>
object CacheMacroImpl {
/**
*
* @param fnTypeParams - Type params of annotation instance, remember our cache macro is generic `class cache[K, V]`,
this will capture Seq(K, V)
* @param cacheExpr - Argument pass to `cache` macro, should be type of `CacheBackEnd[K, V]`
* @param annotatedDef - Methods that is annotated
*/
def expand(fnTypeParams: Seq[Type], cacheExpr: Term.Arg, annotatedDef: Defn.Def): Term = {

Motivation

Informally, kalman filter helps us to improve estimation of data when measurement is subject to noise. 3 basic concepts to understand

Measurement

Data collected, it is inaccurate due to noise and also lack of accuracy due to collection mechanism, ie. inaccurate sensor

typically denoted as Z

@qingwei91
qingwei91 / TypedQuery.scala
Created February 10, 2019 16:42
Recursion Scheme for GADT examples
// Recursive GADT
sealed trait Query[A]
case object QueryString extends Query[String]
case object QueryBool extends Query[Boolean]
case class QueryPath[A](path: String, next: Query[A]) extends Query[A]
// sample data
// {
// simplified
sealed trait Query[A]
case object QueryString extends Query[String]
case object QueryBool extends Query[Boolean]
case class QueryPath[A](path: String, next: Query[A]) extends Query[A]
// sample data
// {
// "oh": {
// "my": "zsh"
// }
def typeMatch[A, B](a: A, b: B)(implicit eq: A=:=B) = ()
val queryString = QueryPath("my", QueryString)
val queryNestedString = QueryPath("my", QueryPath("oh", QueryString))
typeMatch(queryString, queryNestedString) // compiles
sealed trait QueryF[+F[_], A]
case object QueryStringF extends QueryF[Nothing, String]
case object QueryBoolF extends QueryF[Nothing, Boolean]
case class QueryPathF[F[_], A](path: String, next: F[A]) extends QueryF[F, A]
// compiles with `-Ypartial-unification` compiler flag
val expression = QueryPathF("oh", QueryPathF("my", QueryStringF))