Skip to content

Instantly share code, notes, and snippets.

@andyscott
Created March 13, 2017 05:34
Show Gist options
  • Save andyscott/3ad551eb95efb01e5fff8c033a4cb1ca to your computer and use it in GitHub Desktop.
Save andyscott/3ad551eb95efb01e5fff8c033a4cb1ca to your computer and use it in GitHub Desktop.
/* -
* Mezzo [core]
*/
package mezzo
import scala.Predef.<:<
import scala.reflect.ClassTag
import shapeless._
import shapeless.labelled._
case class Node[I, O](
name: String
)
sealed trait Algebra[F[_]] {
type Out <: HList
def ops: Out
}
object Algebra {
type Aux[F[_], O] = Algebra[F] { type Out = O }
implicit def fromBuildAlgebra[F[_], CF <: Coproduct, LF <: HList, O <: HList](
implicit
gen : LabelledGeneric.Aux[F[_], CF],
ev : ops.coproduct.ToHList.Aux[CF, LF],
build: BuildAlgebra.Aux[F, LF, O]
): Algebra.Aux[F, O] = new Algebra[F] {
type Out = O
val ops: Out = build.ops
}
}
sealed trait BuildAlgebra[F[_], R] {
type Out <: HList
def ops: Out
}
object BuildAlgebra {
type Aux[F[_], R, O] = BuildAlgebra[F, R] { type Out = O }
implicit def buildAlgebraHNil[F[_]]: BuildAlgebra.Aux[F, HNil, HNil] =
new BuildAlgebra[F, HNil] {
type Out = HNil
val ops: Out = HNil
}
implicit def buildAlgebraHCons[F[_], A, FA: ? <:< F[A], K <: Symbol, RT <: HList, T <: HList](
implicit
tail: Lazy[BuildAlgebra.Aux[F, RT, T]],
wit : Witness.Aux[K],
ctA : ClassTag[A]
): BuildAlgebra.Aux[F, FieldType[K, FA] :: RT, Node[FieldType[K, FA], A] :: T] = new BuildAlgebra[F, FieldType[K, FA] :: RT] {
type Out = Node[FieldType[K, FA], A] :: T
val ops: Out = Node[FieldType[K, FA], A](wit.value.name) :: tail.value.ops
}
}
import scala.Predef._
sealed abstract class CounterOp[A] extends Product with Serializable
object CounterOp {
case class Adjust(delta: Long) extends CounterOp[Long]
case object Reset extends CounterOp[Unit]
case object Read extends CounterOp[Long]
}
object DummyApp extends App {
val alg = the[Algebra[CounterOp]]
println(alg.ops)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment