Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save andimiller/ac6f84c945d1d1f3bdf6e9a492489b6c to your computer and use it in GitHub Desktop.
Save andimiller/ac6f84c945d1d1f3bdf6e9a492489b6c to your computer and use it in GitHub Desktop.
/*
name := "circe-droste-parser"
version := "0.1"
scalaVersion := "2.12.8"
libraryDependencies += "io.circe" %% "circe-rs" % "0.12.3"
libraryDependencies += "io.circe" %% "circe-literal" % "0.12.3"
libraryDependencies += "io.circe" %% "circe-parser" % "0.12.3"
libraryDependencies += "io.circe" %% "circe-generic" % "0.12.3"
libraryDependencies += "io.higherkindness" %% "droste-core" % "0.7.0"
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)
*/
import cats._
import io.circe.droste._
import higherkindness.droste._
import higherkindness.droste.scheme._
import io.circe.Decoder.Result
import io.circe.{Decoder, DecodingFailure, Encoder, Json}
import io.circe.generic.semiauto._
import io.circe.literal._
import io.circe.syntax._
import cats.implicits._
object Example {
case class Dog(name: String, child: Option[Dog])
case class DogF[F](name: String, child: Option[F])
object DogF {
implicit val dogfEncoder: Encoder[DogF[Json]] = deriveEncoder[DogF[Json]]
implicit val dogfDecoder: Decoder[DogF[Json]] = deriveDecoder[DogF[Json]]
implicit val functor = new Functor[DogF] {
def map[A, B](fa: DogF[A])(f: A => B): DogF[B] = DogF(fa.name, fa.child.map(f))
}
implicit val traverse = new Traverse[DogF] {
def traverse[G[_], A, B](fa: DogF[A])(f: A => G[B])(implicit evidence$1: Applicative[G]): G[DogF[B]] =
fa.child.traverse(f).map(child => DogF(fa.name, child) )
def foldLeft[A, B](fa: DogF[A], b: B)(f: (B, A) => B): B =
fa.child.foldLeft(b)(f)
def foldRight[A, B](fa: DogF[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
fa.child.foldRight(lb)(f)
}
}
def project(d: DogF[Json]): Json = d.asJson
def projectM(d: DogF[Json]): Result[Json] = d.asJson.asRight[DecodingFailure]
def embed(d: Json): Decoder.Result[DogF[Json]] = d.as[DogF[Json]]
val alg: Algebra[DogF, Json] = Algebra(project)
val algM: AlgebraM[Result, DogF, Json] = alg.lift[Result]
val coalgM: CoalgebraM[Result, DogF, Json] = CoalgebraM(embed)
val names: Algebra[DogF, List[String]] = Algebra({(d: DogF[List[String]]) => d.name :: d.child.toList.flatten })
val run: Json => Result[List[String]] = hyloM(names.lift[Result], coalgM)
def main(args: Array[String]): Unit = {
println(run(json"""{"name": "bob", "child": {"name": "marge"}}"""))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment