Created
February 28, 2015 21:00
-
-
Save japgolly/9988c96ec3dc454f6e4b to your computer and use it in GitHub Desktop.
AADT folds
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Example { | |
// Data types | |
sealed trait Base { | |
sealed trait Token | |
} | |
sealed trait PlainText extends Base { | |
case class PlainText(text: String) extends Token | |
} | |
sealed trait NewLine extends Base { | |
case class NewLine() extends Token | |
} | |
sealed trait Link extends Base { | |
case class Link(url: String) extends Token | |
} | |
sealed trait Quote extends Base { | |
case class Quote(content: List[Token]) extends Token | |
} | |
object BlogTitle extends PlainText with Link with Quote | |
object BlogComment extends PlainText with NewLine with Quote | |
// Folds. | |
// Could just as easily be Base.fold, BlogTitle.fold, BlogComment.fold | |
def foldAny[A](a: PlainText#PlainText => A, | |
b: NewLine #NewLine => A, | |
c: Link #Link => A, | |
d: Quote #Quote => A): Base#Token => A = { | |
case t: PlainText#PlainText => a(t) | |
case t: NewLine #NewLine => b(t) | |
case t: Link #Link => c(t) | |
case t: Quote #Quote => d(t) | |
} | |
def foldBlogTitle[A](a: BlogTitle.PlainText => A, | |
c: BlogTitle.Link => A, | |
d: BlogTitle.Quote => A): BlogTitle.Token => A = { | |
case t: BlogTitle.PlainText => a(t) | |
case t: BlogTitle.Link => c(t) | |
case t: BlogTitle.Quote => d(t) | |
} | |
def foldBlogComment[A](a: BlogComment.PlainText => A, | |
b: BlogComment.NewLine => A, | |
d: BlogComment.Quote => A): BlogComment.Token => A = { | |
case t: BlogComment.PlainText => a(t) | |
case t: BlogComment.NewLine => b(t) | |
case t: BlogComment.Quote => d(t) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another encoding using "folds" (or so-called "object algebras"), where you can leave your existing
Token
classes outside of aBase
trait: