Skip to content

Instantly share code, notes, and snippets.

@gclaramunt
Last active August 29, 2015 13:56
Show Gist options
  • Save gclaramunt/9097036 to your computer and use it in GitHub Desktop.
Save gclaramunt/9097036 to your computer and use it in GitHub Desktop.
Evil trick using implicits to customize error messages in a validation
abstract class MyTry[T] {
def get: T
def flatMap[U](f: T => MyTry[U]): MyTry[U]
def map[U](f: T => U): MyTry[U]
def filter(p: T => Boolean)(implicit msg:Msg[T]): MyTry[T]
}
object MyTry {
def apply[T](r: => T): MyTry[T] =
try MySuccess(r) catch {
case e => MyFailure(e.toString)
}
}
final case class MyFailure[T](val exception: String) extends MyTry[T] {
def get: T = throw new Exception(msg)
def flatMap[U](f: T => MyTry[U]): MyTry[U] = this.asInstanceOf[MyTry[U]]
def map[U](f: T => U): MyTry[U] = this.asInstanceOf[MyTry[U]]
def filter(p: T => Boolean)(implicit msg:Msg[T]): MyTry[T] = this
}
final case class MySuccess[T](value: T) extends MyTry[T] {
def get = value
def flatMap[U](f: T => MyTry[U]): MyTry[U] =
try f(value)
catch {
case e => MyFailure(e.toString)
}
def map[U](f: T => U): MyTry[U] = MyTry[U](f(value))
def filter(p: T => Boolean)(implicit msg:Msg[T]): MyTry[T] = {
try {
if (p(value)) this
else MyFailure(msg.txt)
} catch {
case e => MyFailure(e.toString)
}
}
}
trait Msg[T]{
val txt:String
}
implicit val strMsg= new Msg[String]{ val txt="no Strings!"}
implicit val intMsg= new Msg[Int]{ val txt="no Ints!"}
for { a<- MyTry("123") } yield a
for { a<- MyTry("123") if (a=="2") } yield a
// res7: MyTry[java.lang.String] = MyFailure(no Strings!)
for { a<- MyTry(123) } yield a
for { a<- MyTry(123) if (a==2) } yield a
//res8: MyTry[Int] = MyFailure(no Ints!)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment