Skip to content

Instantly share code, notes, and snippets.

@chenharryhua
Last active October 2, 2016 08:07
Show Gist options
  • Save chenharryhua/cbf1fb6aea3307aeb660ba5e5e06461f to your computer and use it in GitHub Desktop.
Save chenharryhua/cbf1fb6aea3307aeb660ba5e5e06461f to your computer and use it in GitHub Desktop.
package dsl
import scalaz._
import Scalaz._
object MyOptionFree extends App {
sealed trait ElasticF[T] extends Product with Serializable
final case class Bool[T](seq: Seq[T]) extends ElasticF[T]
final case class Term[T](name: String, value: Option[String]) extends ElasticF[T]
implicit val elasticFunctor = new Functor[ElasticF] {
def map[A, B](fa: ElasticF[A])(f: A => B): ElasticF[B] = fa match {
case Bool(seq) => Bool(seq.map(f))
case Term(n, v) => Term(n, v)
}
}
type Elastic = Cofree[ElasticF, Unit]
def bool(bs: Elastic*) = Cofree[ElasticF, Unit]((), Bool(bs.toSeq))
def term(n: String, v: Option[String]): Elastic = Cofree[ElasticF, Unit]((), Term(n, v))
val opTerm1 = term("a", some("v1"))
val opTerm2 = none
val opTerm3 = term("b", some("v2"))
val kkk: Elastic = bool(term("c", some("v3")), term("n", none), bool(bool(term("b", some("v2")))))
val kkknon = bool(term("c", none), term("a", some("ok")), bool(term("x", none)))
def decorate(e: Elastic): Cofree[ElasticF, Option[String]] = e match {
case Cofree(f, t) => t match {
case Bool(s) =>
val kk = s.map(x => x.extend(decorate(_)).head)
val ss = kk.map(_.head).collect { case Some(x) => x }
val ks = ss.mkString(",")
if (ss.isEmpty)
Cofree[ElasticF, Option[String]](None, Bool(kk))
else
Cofree[ElasticF, Option[String]](Some(ks), Bool(kk))
case Term(a, b) =>
b match {
case Some(x) => Cofree[ElasticF, Option[String]](Some(s"term($a,${x})"), Term(a, b))
case None => Cofree[ElasticF, Option[String]](None, Term(a, b))
}
}
}
println(decorate(kkk).head)
println(decorate(kkknon).head)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment