Skip to content

Instantly share code, notes, and snippets.

@aryairani
Created December 15, 2012 17:29
Show Gist options
  • Save aryairani/4297410 to your computer and use it in GitHub Desktop.
Save aryairani/4297410 to your computer and use it in GitHub Desktop.
// scalaVersion := "2.10.0-RC5"
// libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.0.0-M6" cross CrossVersion.full
import scalaz.{OptionT,Writer}
type Issue = String
type ListWriter[+A] = Writer[List[Issue],A]
type Box[+A] = OptionT[ListWriter,A]
object EmptyBox {
def unapply[A](b: Box[A]): Option[List[Issue]] =
b.run.value match { // value returns Id.Id[Option[A]], which I understand <:< Option[A]
case Some(_) => None
case None => Some(b.run.written)
}
}
/*
warning: unreachable code
case None => Some(b.run.written)
^
*/
object Box {
def apply[A](a : Option[A], issues : List[Issue]): Box[A] = {
val writer: ListWriter[Option[A]] = Writer(issues,a)
OptionT(writer)// IDEA erroneously shows an error
}
def empty[A]: Box[A] = Box(Option.empty[A], Nil)
def empty[A](issue: Issue): Box[A] = Box(None, List(issue))
def empty[A](issues: List[Issue]): Box[A] = Box(None, issues)
def apply[A](a: A): Box[A] = Box(Some(a), Nil)
def apply[A](a: A, issue: Issue): Box[A] = Box(Some(a), List(issue))
def apply[A](a: A, issues: List[Issue]): Box[A] = Box(Some(a), issues)
}
val box1 = Box.apply(3, "full")
val box2 = Box.empty[Int]("empty")
box1 match { case EmptyBox(s) => s; case _ => List("no match") } // List("no match")
box2 match { case EmptyBox(s) => s; case _ => List("no match") } // List("empty")
// so this seems proof that both paths are executing
box1.run.value match { case Some(x) => "match"; case None => "no match" }
/* warning: unreachable code
box1.run.value match { case Some(x) => "match"; case None => "no match" }
^
res24: String = match
*/
box2.run.value match { case Some(x) => "match"; case None => "no match" }
/* warning: unreachable code
box2.run.value match { case Some(x) => "match"; case None => "no match" }
^
res25: String = no match
*/
// No warnings, same output
(box1.run.value: Option[Int]) match { case Some(x) => "match"; case None => "no match" }
// res11: String = match
(box2.run.value: Option[Int]) match { case Some(x) => "match"; case None => "no match" }
// res12: String = no match
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment