Skip to content

Instantly share code, notes, and snippets.

@norswap
Created January 18, 2016 16:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save norswap/2aed7e6beb75b44b0e3c to your computer and use it in GitHub Desktop.
Save norswap/2aed7e6beb75b44b0e3c to your computer and use it in GitHub Desktop.
Object Algebras in Kotlin
// Basic setup
interface Exp
data class Lit(val x: Int): Exp
data class Add(val x: Exp, val y: Exp): Exp
interface IntAlg<A>
{
fun lit(x: Int): A
fun add(x: A, y: A): A
}
open class IntFactory: IntAlg<Exp>
{
override fun lit(x: Int) = Lit(x)
override fun add(x: Exp, y: Exp) = Add(x, y)
}
fun <A> exp(v: IntAlg<A>) = v.add(v.lit(42), v.lit(0x52))
val exp0: Exp = exp(IntFactory())
// Adding a print operation
interface Print { fun print(): String }
// Can I haz SAM-conversion plz?
fun Print(f: () -> String) = object: Print { override fun print() = f() }
open class IntPrint: IntAlg<Print>
{
override fun lit(x: Int) = Print { x.toString() }
override fun add(x: Print, y: Print) = Print { "${x.print()} + ${y.print()}" }
}
val exp1: Print = exp(IntPrint())
// Adding new data variants
data class Bool(val x: Boolean): Exp
data class Iff(val x: Exp, val y: Exp, val z: Exp): Exp
interface IntBoolAlg<A>: IntAlg<A>
{
fun bool(b: Boolean): A
fun iff(x: A, y: A, z: A): A
}
open class IntBoolFactory: IntFactory(), IntBoolAlg<Exp>
{
override fun bool(x: Boolean) = Bool(x)
override fun iff(x: Exp, y: Exp, z: Exp) = Iff(x, y, z)
}
fun <A> exp2(v: IntBoolAlg<A>) = v.iff(v.bool(false), exp(v), v.lit(0))
val exp2: Exp = exp2(IntBoolFactory())
// Making the data variants printable
open class IntBoolPrint: IntPrint(), IntBoolAlg<Print>
{
override fun bool(b: Boolean) = Print { b.toString() }
override fun iff(x: Print, y: Print, z: Print)
= Print { "if (${x.print()}) then ${y.print()} else ${z.print()}" }
}
val exp3: Print = exp2(IntBoolPrint())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment