Skip to content

Instantly share code, notes, and snippets.

@adilakhter
Last active September 3, 2018 11:08
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 adilakhter/4d6973d892c9366f20245d9ddd9beef0 to your computer and use it in GitHub Desktop.
Save adilakhter/4d6973d892c9366f20245d9ddd9beef0 to your computer and use it in GitHub Desktop.
refactoring to typeclass
object typeclass extends App {
// Note: This domain model was given
// Simplified version is as follows:
sealed trait Attribute
case class PageLoad (e: String) extends Attribute
case class AdobeSinkableItem(e: String) extends Attribute
case class WebtrekkSinkableItem(e: Int) extends Attribute
case class ErrorItem(e: String)
// Type class is deifned that convert any item to its Sinkable form
trait Sinkable[T, R] {
def convertToSinkable(t: T): R
}
object Sinkable {
implicit val toWebTrekSinkable = new Sinkable[PageLoad, WebtrekkSinkableItem] {
def convertToSinkable(t: PageLoad): WebtrekkSinkableItem = WebtrekkSinkableItem(1)
}
implicit val toWebTrekErrorSinable = new Sinkable[ErrorItem, WebtrekkSinkableItem] {
def convertToSinkable(t: ErrorItem): WebtrekkSinkableItem = WebtrekkSinkableItem(9999)
}
implicit val toAdobeSinkable = new Sinkable[PageLoad, AdobeSinkableItem] {
def convertToSinkable(t: PageLoad): AdobeSinkableItem = AdobeSinkableItem(t.e)
}
}
sealed trait Sink [R] {
def toSink[T](t: T)(implicit converter: Sinkable[T, R]): Boolean
}
class WebTrekkSink extends Sink[WebtrekkSinkableItem] {
def toSink[T](t: T)(implicit converter: Sinkable[T, WebtrekkSinkableItem]): Boolean = {
val webTrekkSinkable = converter.convertToSinkable(t)
// publish to WebTrek Sink
println(webTrekkSinkable)
true // Use Either or other HKT that is more suitable.
}
}
class AdobeSink extends Sink[AdobeSinkableItem] {
def toSink[T](t: T)(implicit converter: Sinkable[T, AdobeSinkableItem]): Boolean = {
val adobeSinkable = converter.convertToSinkable(t)
// publish to Adobe Sink
println(adobeSinkable)
true // This is wrong.
// Use Either or other HKT that is more suitable and capture the return type.
}
}
val p = PageLoad("1")
val e = ErrorItem("unknown error")
val aSink: Sink[WebtrekkSinkableItem] = new WebTrekkSink
val bSink: Sink[AdobeSinkableItem] = new AdobeSink
aSink.toSink(e)
aSink.toSink(p)
bSink.toSink(p)
}
@adilakhter
Copy link
Author

This can be further simplified with a polymorphic publish as follows:

def publish[T, R] (t: T, s: Sink[R]) (implicit c: Sinkable[T , R]) =
    s.toSink(t)

  publish(p, aSink)
  publish(e, aSink)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment