Skip to content

Instantly share code, notes, and snippets.

@chenharryhua
Last active April 16, 2017 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chenharryhua/d19607287fb1f8dfa198609f7f20eb92 to your computer and use it in GitHub Desktop.
Save chenharryhua/d19607287fb1f8dfa198609f7f20eb92 to your computer and use it in GitHub Desktop.
object enhanced extends App {
final class MyLog[Annotation] extends LogTreeSyntax[Annotation] {
implicit object NothingShow extends Show[Nothing] {
override def shows(n: Nothing): String = ""
}
override implicit def logTreeShow(implicit annotationShow: Show[Annotation]) = new Show[LogTree] {
override def shows(t: LogTree) = toList(t).map(line ⇒ " " * line._1 + line._2).mkString(System.getProperty("line.separator"))
private def toList(tree: LogTree, depth: Int = 0): List[(Int, String)] =
line(depth, tree.rootLabel) :: tree.subForest.flatMap(toList(_, depth + 1)).toList
private def line(depth: Int, label: LogTreeLabel[Annotation]) = (depth, showAnnotations(label.annotations, showSuccess(label.success(), showDescription(label))))
private def showAnnotations(annotations: Set[Annotation], line: String) =
if (annotations.isEmpty) line else line + " - [" + annotations.map(annotationShow.show).mkString(", ") + "]"
private def showDescription(label: LogTreeLabel[Annotation]) = label.fold(_.description, _ ⇒ "No Description")
private def showSuccess(success: Boolean, s: String) = if (success) "Success: " + s else "Failed: " + s
}
private val eitherWriter = EitherT.monadListen[LogTreeWriter, LogTree, String]
private def failure[V](description: String, tree: LogTree): DescribedComputation[V] =
for {
_ ← eitherWriter.tell(tree)
err ← eitherWriter.left[V](description)
} yield err
private def success[V](value: V, tree: LogTree): DescribedComputation[V] =
for {
_ ← eitherWriter.tell(tree)
res ← eitherWriter.right[V](value)
} yield res
implicit class BranchLabelingSyntax2(description: String)
extends BranchLabelingSyntax(description) {
def ~<*[V](dc: DescribedComputation[V]): DescribedComputation[V] =
dc.run.value match {
case -\/(_) ⇒ failure(description, branchHoister(dc.run.written, description, false))
case \/-(value) ⇒ success(value, branchHoister(dc.run.written, description, true))
}
def branchHoister(tree: LogTree, description: String, b: Boolean): LogTree = tree match {
case Node(l: UndescribedLogTreeLabel[Annotation], children) ⇒ Node(DescribedLogTreeLabel(description, b, l.annotations), children)
case Node(l: DescribedLogTreeLabel[Annotation], children) ⇒ Node(DescribedLogTreeLabel(description, b), Stream(tree))
}
}
}
val mylog = new MyLog[Nothing]
import mylog._
val rec = "test" ~<* {
val dc = for {
a <- some(1) ~>? "first param"
b <- some(2) ~>? "second param"
c <- none[Int] ~>? "wrong"
} yield (a + b)
dc.handleError { x => 1 ~> "recovered" }
}
println(rec.run.written.shows)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment