Skip to content

Instantly share code, notes, and snippets.

@japgolly japgolly/boopickle.scala
Last active Oct 23, 2017

Embed
What would you like to do?
Fixpoint type serialisation
// Can't use the usual morphisms, cata = depth-first, ana = breadth-first evaluation order.
// You'd think there'd be a way to describe the effects and execute them in different order but I stopped trying.
def pickleFix[F[_]: Functor](implicit p: Pickler[F[Unit]]): Pickler[Fix[F]] =
new Pickler[Fix[F]] {
override def pickle(f: Fix[F])(implicit state: PickleState): Unit = {
// val fUnit = Functor[F].void(f.unfix)
// p.pickle(fUnit)
// Functor[F].map(f.unfix)(pickle)
// Compared to ↑, this ↓ is generally on-par for small trees, and around 30% faster for larger, deeper trees
val fields = new collection.mutable.ArrayBuffer[Fix[F]](32)
val fUnit = Functor[F].map(f.unfix) { a =>
fields += a
()
}
p.pickle(fUnit)
fields.foreach(pickle)
()
}
override def unpickle(implicit state: UnpickleState) = {
val fUnit = p.unpickle
Fix(Functor[F].map(fUnit)(_ => unpickle))
}
}
// Nice and easy with uPickle.
def pickleFix[F[_]: Functor](implicit rw: ReadWriter[F[Js.Value]]): ReadWriter[Fix[F]] = {
val algebra : Algebra [F, Js.Value] = rw.write
val coalgebra: Coalgebra[F, Js.Value] = rw.read
ReadWriter[Fix[F]](
Recursion.cata(algebra)(_),
{ case j => Recursion.ana(coalgebra)(j) })
}
implicit val pickleJsValue: ReadWriter[Js.Value] =
ReadWriter[Js.Value](Identity.apply, { case j => j })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.