Skip to content

Instantly share code, notes, and snippets.

@nuttycom
Created January 11, 2013 04:41
Show Gist options
  • Save nuttycom/4507997 to your computer and use it in GitHub Desktop.
Save nuttycom/4507997 to your computer and use it in GitHub Desktop.
This is a bit of a curiosity exploring the space of the expression problem by using a fold to define an algebra over multiple subtrees (and multiple levels) of an inheritance hierarchy. I'm not sure if it's good for anything yet, but it does allow for some interesting patterns using the combination of polymorphic dispatch and a fold.
trait A {
// define an algebra over the known space of subtypes
def fold[X](af: A => X, bf: B => X, cf: C => X): X
}
trait B extends A {
def fold[X](af: A => X, bf: B => X, cf: C => X): X = bf(this)
}
trait C extends B {
override def fold[X](af: A => X, bf: B => X, cf: C => X): X = cf(this)
}
// some other module then takes advantage of the fact that A is open
trait A0 extends A {
// this module can participate fully in any functionality that was defined
// for A. Note that since C0 extends C, it can participate "more specifically" in
// the algebra defined by its parent
override def fold[X](af: A => X, bf: B => X, cf: C => X): X = fold0(af, af, cf)
// anything that knows about the A0 type can make use of its specific refinements
def fold0[X](af: A0 => X, bf: B0 => X, cf: C0 => X): X
}
trait B0 extends A0 {
def fold0[X](af: A0 => X, bf: B0 => X, cf: C0 => X): X = bf(this)
}
trait C0 extends C with B0 {
override def fold0[X](af: A0 => X, bf: B0 => X, cf: C0 => X): X = cf(this)
}
@copumpkin
Copy link

And "flat" folds are basically pattern matching! :O

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment