Last active
March 23, 2022 12:19
-
-
Save igstan/1ecadd5ea5d2864446b40e65663554c4 to your computer and use it in GitHub Desktop.
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
trait SACVisitor[R] { | |
def c1(a: Int): R | |
def c2(a: R, b: R): R | |
} | |
sealed trait SAC extends Product with Serializable { | |
def fold[R](visitor: SACVisitor[R]): R | |
} | |
object SAC { | |
final case class C1(a: Int) extends SAC { | |
def fold[R](visitor: SACVisitor[R]): R = | |
visitor.c1(a) | |
} | |
final case class C2(a: SAC, b: SAC) extends SAC { | |
def fold[R](visitor: SACVisitor[R]): R = | |
// Explicit recursive calls in the "recursive points". | |
visitor.c2(a.fold(visitor), b.fold(visitor)) | |
} | |
def sum(sac: SAC): Int = | |
sac.fold(new SACVisitor[Int] { | |
override def c1(a: Int) = a | |
// Recursive points have already been handled, folded, by `fold`. | |
override def c2(a: Int, b: Int) = a + b | |
}) | |
} |
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
// Alternatively, `fold` could be defined in the base trait using pattern matching. | |
trait SACVisitor[R] { | |
def c1(a: Int): R | |
def c2(a: R, b: R): R | |
} | |
sealed trait SAC extends Product with Serializable { | |
final def fold[R](visitor: SACVisitor[R]): R = | |
this match { | |
case SAC.C1(a) => visitor.c1(a) | |
case SAC.C2(a, b) => visitor.c2(a.fold(visitor), b.fold(visitor)) | |
} | |
} | |
object SAC { | |
final case class C1(a: Int) extends SAC | |
final case class C2(a: SAC, b: SAC) extends SAC | |
def sum(sac: SAC): Int = | |
sac.fold(new SACVisitor[Int] { | |
override def c1(a: Int) = a | |
override def c2(a: Int, b: Int) = a + b | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment