Ingredients of a type class and its usage
- an interface (the type class) with type parameter (trait LoggerWrapper)
- a companion object for the interface, providing implementations (object LoggerWrapper)
- a user trait to mixin the desired functionality using context bounds (UsingALogger)
- and a class using it (MyMain)
/** * this is the type class * @tparam T type to "select" logger implementations */ @annotation.implicitNotFound(msg = "Cannot find LoggerWrapper type class for ${T}\n Please provide additional implementation") trait LoggerWrapper[T] { def doLog(v: T) } /** * type class companion object with two different * implementations */ object LoggerWrapper { /**implementation for Int */ implicit def getLoggerForInt = new LoggerWrapper[Int] { def doLog(v: Int) = println("Int implementation logging Value: " + v) } /**implementation for String */ implicit def getLoggerForString = new LoggerWrapper[String] { def doLog(v: String) = println("String implementation logging value: " + v) } } /** * Mixin to provide logging functionality */ trait UsingALogger { /**"lookup" implementation using context bounds*/ def log[T: LoggerWrapper](v: T) = implicitly[LoggerWrapper[T]].doLog(v) } /** * class that wants to use a logger */ object MyMain extends App with UsingALogger { /** * prints: "String implementation logging Value: MySTRING" */ log("MySTRING") /** * prints: "Int implementation logging Value: 1234" */ log(1234) /** * produces compile error: * error: Cannot find LoggerWrapper type class for Double * Please provide additional implementation * log(1234.5) */ //log(1234.5) }
prints out
String implementation logging value: MySTRING Int implementation logging Value: 1234
or throws compiler error (comment in log(1234.5))
error: Cannot find LoggerWrapper type class for Double Please provide additional implementation log(1234.5)
Advantages:
- type-safe injection
- No extra framework (means Spring avoided)
- Composability of dependencies and implementations
- overwritable default implementations
- better abstraction
Connect with me on Google+